diff --git a/.changeset/cyan-crabs-explode.md b/.changeset/cyan-crabs-explode.md
new file mode 100644
index 00000000000..5018e2d555c
--- /dev/null
+++ b/.changeset/cyan-crabs-explode.md
@@ -0,0 +1,5 @@
+---
+"chainlink": minor
+---
+
+Add support for workflow jobs to Operator UI #wip #added
diff --git a/.changeset/flat-guests-marry.md b/.changeset/flat-guests-marry.md
new file mode 100644
index 00000000000..c1eb6549a96
--- /dev/null
+++ b/.changeset/flat-guests-marry.md
@@ -0,0 +1,6 @@
+---
+"chainlink": minor
+---
+
+#internal Gas Estimator L1Oracles to be chain specific
+#removed cmd/arbgas
diff --git a/.changeset/forty-feet-train.md b/.changeset/forty-feet-train.md
new file mode 100644
index 00000000000..f5ea60fd061
--- /dev/null
+++ b/.changeset/forty-feet-train.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+Bumping chainlink-automation version to v1.0.3
diff --git a/.changeset/fresh-lizards-love.md b/.changeset/fresh-lizards-love.md
new file mode 100644
index 00000000000..8e6e5d5cfef
--- /dev/null
+++ b/.changeset/fresh-lizards-love.md
@@ -0,0 +1,5 @@
+---
+"chainlink": minor
+---
+
+#internal Updates required to work with chainlink-common changes to support grpc streams for capabilities
diff --git a/.changeset/gold-bottles-tell.md b/.changeset/gold-bottles-tell.md
new file mode 100644
index 00000000000..5289f368a55
--- /dev/null
+++ b/.changeset/gold-bottles-tell.md
@@ -0,0 +1,5 @@
+---
+"chainlink": minor
+---
+
+#added : Re-enable abandoned transaction tracker
diff --git a/.changeset/great-rockets-obey.md b/.changeset/great-rockets-obey.md
new file mode 100644
index 00000000000..b90bc810a01
--- /dev/null
+++ b/.changeset/great-rockets-obey.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+#wip Keystone wrapper regenerate
diff --git a/.changeset/hot-dryers-flash.md b/.changeset/hot-dryers-flash.md
new file mode 100644
index 00000000000..8423420589d
--- /dev/null
+++ b/.changeset/hot-dryers-flash.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+core/services: update llo & versioning to use sqlutil #internal
diff --git a/.changeset/hungry-ways-add.md b/.changeset/hungry-ways-add.md
new file mode 100644
index 00000000000..657494de605
--- /dev/null
+++ b/.changeset/hungry-ways-add.md
@@ -0,0 +1,6 @@
+---
+"chainlink": patch
+---
+
+#bugfix
+vrf fix replay number of blocks logic and add logging for job specs
diff --git a/.changeset/loud-peaches-beg.md b/.changeset/loud-peaches-beg.md
new file mode 100644
index 00000000000..cd880ae5f5c
--- /dev/null
+++ b/.changeset/loud-peaches-beg.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+support decimals #added
diff --git a/.changeset/lucky-windows-taste.md b/.changeset/lucky-windows-taste.md
new file mode 100644
index 00000000000..bfcf559adb5
--- /dev/null
+++ b/.changeset/lucky-windows-taste.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+Validate support for postgresql-client 16, and update docker image's bundled postgresql-client from 15 to 16. #nops #updated
diff --git a/.changeset/many-pillows-reflect.md b/.changeset/many-pillows-reflect.md
new file mode 100644
index 00000000000..6de57ecc2a4
--- /dev/null
+++ b/.changeset/many-pillows-reflect.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+core/services/keeper: switch to sqlutil.DataSource #internal
diff --git a/.changeset/new-forks-grab.md b/.changeset/new-forks-grab.md
new file mode 100644
index 00000000000..cb078beb29b
--- /dev/null
+++ b/.changeset/new-forks-grab.md
@@ -0,0 +1,5 @@
+---
+"chainlink": removed
+---
+
+Drop unused queryTimeout config from TXM strategy #internal
diff --git a/.changeset/odd-horses-fix.md b/.changeset/odd-horses-fix.md
new file mode 100644
index 00000000000..290d82bebfe
--- /dev/null
+++ b/.changeset/odd-horses-fix.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+contracts work
diff --git a/.changeset/orange-squids-kick.md b/.changeset/orange-squids-kick.md
new file mode 100644
index 00000000000..a934e70063d
--- /dev/null
+++ b/.changeset/orange-squids-kick.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+#internal Remote Trigger setup
diff --git a/.changeset/poor-socks-travel.md b/.changeset/poor-socks-travel.md
new file mode 100644
index 00000000000..88986845095
--- /dev/null
+++ b/.changeset/poor-socks-travel.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+core/services/ocr2/plugins/ocr2keeper/evmregister/v21/upkeepstate: use sqlutil instead of pg.QOpts #internal
diff --git a/.changeset/pretty-flies-fold.md b/.changeset/pretty-flies-fold.md
new file mode 100644
index 00000000000..d67a3117e14
--- /dev/null
+++ b/.changeset/pretty-flies-fold.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+cor/services/relay/evm/mercury: switch to sqlutil.DataStore #internal
diff --git a/.changeset/real-numbers-taste.md b/.changeset/real-numbers-taste.md
new file mode 100644
index 00000000000..d9f545444c2
--- /dev/null
+++ b/.changeset/real-numbers-taste.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+core/services/functions: switch to sqlutil.DataStore #internal
diff --git a/.changeset/rich-jars-flow.md b/.changeset/rich-jars-flow.md
new file mode 100644
index 00000000000..cb72503fe0d
--- /dev/null
+++ b/.changeset/rich-jars-flow.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+Narrowing topic, data_word indexes by adding (evm_chain_id, address, event_sig) to the index definition #db_update
diff --git a/.changeset/soft-hotels-decide.md b/.changeset/soft-hotels-decide.md
new file mode 100644
index 00000000000..75b4cadd4e5
--- /dev/null
+++ b/.changeset/soft-hotels-decide.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+switch more EVM components to use sqlutil.DataStore #internal
diff --git a/.changeset/sweet-sloths-laugh.md b/.changeset/sweet-sloths-laugh.md
new file mode 100644
index 00000000000..cbc72913ec9
--- /dev/null
+++ b/.changeset/sweet-sloths-laugh.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+core/sessions: switch to sqlutil.DataSource #internal
diff --git a/.changeset/swift-horses-unite.md b/.changeset/swift-horses-unite.md
new file mode 100644
index 00000000000..d9d426efe6d
--- /dev/null
+++ b/.changeset/swift-horses-unite.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+core/bridges: use sqlutil.DataSource #internal
diff --git a/.changeset/ten-clouds-collect.md b/.changeset/ten-clouds-collect.md
new file mode 100644
index 00000000000..0408383bd03
--- /dev/null
+++ b/.changeset/ten-clouds-collect.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+#internal
diff --git a/.changeset/tender-crews-jam.md b/.changeset/tender-crews-jam.md
new file mode 100644
index 00000000000..41b4f0a7633
--- /dev/null
+++ b/.changeset/tender-crews-jam.md
@@ -0,0 +1,5 @@
+---
+"chainlink": patch
+---
+
+vrfv2plus - account for num words in coordinator gas overhead in v2plus wrapper
diff --git a/.changeset/weak-emus-reply.md b/.changeset/weak-emus-reply.md
new file mode 100644
index 00000000000..ef0c1fe4dae
--- /dev/null
+++ b/.changeset/weak-emus-reply.md
@@ -0,0 +1,5 @@
+---
+"chainlink": minor
+---
+
+#internal Updated FindTxesWithAttemptsAndReceiptsByIdsAndState method signature to accept int64 for tx ID instead of big.Int
diff --git a/.github/actions/build-sign-publish-chainlink/action.yml b/.github/actions/build-sign-publish-chainlink/action.yml
index 7ed0c911b83..b5bb725098d 100644
--- a/.github/actions/build-sign-publish-chainlink/action.yml
+++ b/.github/actions/build-sign-publish-chainlink/action.yml
@@ -110,6 +110,8 @@ runs:
role-to-assume: ${{ inputs.aws-role-to-assume }}
role-duration-seconds: ${{ inputs.aws-role-duration-seconds }}
aws-region: ${{ inputs.aws-region }}
+ mask-aws-account-id: true
+ role-session-name: build-sign-publish-chainlink
- if: inputs.publish == 'true'
name: Login to ECR
diff --git a/.github/actions/golangci-lint/action.yml b/.github/actions/golangci-lint/action.yml
index 3542c865959..e52dd1aed7b 100644
--- a/.github/actions/golangci-lint/action.yml
+++ b/.github/actions/golangci-lint/action.yml
@@ -2,6 +2,9 @@ name: CI lint for Golang
description: Runs CI lint for Golang
inputs:
# general inputs
+ id:
+ description: Unique metrics collection id
+ required: true
name:
description: Name of the lint action
default: lint
@@ -72,7 +75,7 @@ runs:
if: always()
uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0
with:
- id: chainlink-golang-ci
+ id: chainlink-golang-ci-${{ inputs.id }}
basic-auth: ${{ inputs.gc-basic-auth }}
hostname: ${{ inputs.gc-host }}
org-id: ${{ inputs.gc-org-id }}
diff --git a/.github/scripts/check-changeset-tags.sh b/.github/scripts/check-changeset-tags.sh
new file mode 100755
index 00000000000..579661fe704
--- /dev/null
+++ b/.github/scripts/check-changeset-tags.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# This checks for if at least one tag exists from a list of tags provided in a changeset file
+#
+# TAG LIST:
+# #nops : For any feature that is NOP facing and needs to be in the official Release Notes for the release.
+# #added : For any new functionality added.
+# #changed : For any change to the existing functionality.
+# #removed : For any functionality/config that is removed.
+# #updated : For any functionality that is updated.
+# #deprecation_notice : For any upcoming deprecation functionality.
+# #breaking_change : For any functionality that requires manual action for the node to boot.
+# #db_update : For any feature that introduces updates to database schema.
+# #wip : For any change that is not ready yet and external communication about it should be held off till it is feature complete.
+# #bugfix - For bug fixes.
+# #internal - For changesets that need to be excluded from the final changelog.
+
+if [ $# -eq 0 ]; then
+ echo "Error: No changeset file path provided."
+ exit 1
+fi
+
+CHANGESET_FILE_PATH=$1
+tags_list=( "#nops" "#added" "#changed" "#removed" "#updated" "#deprecation_notice" "#breaking_change" "#db_update" "#wip" "#bugfix" "#internal" )
+has_tags=false
+
+if [[ ! -f "$CHANGESET_FILE_PATH" ]]; then
+ echo "Error: File '$CHANGESET_FILE_PATH' does not exist."
+ exit 1
+fi
+
+while IFS= read -r line; do
+ for tag in "${tags_list[@]}"; do
+ if [[ "$line" == *"$tag"* ]]; then
+ echo "Found tag: $tag in $CHANGESET_FILE_PATH"
+ has_tags=true
+ fi
+ done
+done < "$CHANGESET_FILE_PATH"
+
+if [[ "$has_tags" == false ]]; then
+ echo "Error: No tags found in $CHANGESET_FILE_PATH"
+fi
+
+echo "has_tags=$has_tags" >> $GITHUB_OUTPUT
diff --git a/.github/workflows/build-publish-develop.yml b/.github/workflows/build-publish-develop.yml
index def6aca189a..1df1720d714 100644
--- a/.github/workflows/build-publish-develop.yml
+++ b/.github/workflows/build-publish-develop.yml
@@ -91,12 +91,8 @@ jobs:
-l "app=${K8S_NAMESPACE}" \
-o custom-columns=:metadata.name --no-headers)
- IFS=$'\n' read -r -d '' -a deployment_names_arr <<< "$deployment_node_names" || :
- for name in "${deployment_names_arr[@]}"; do
- echo "Restarting deployment: $name"
- kubectl --namespace "${K8S_NAMESPACE}" \
- rollout restart "deployment/${name}"
- done
+ echo "Restarting deployments: $deployment_node_names"
+ kubectl rollout restart deployment $deployment_node_names --namespace "${K8S_NAMESPACE}"
- name: Collect Metrics
if: always()
diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml
index d243a75467e..00089d1fdde 100644
--- a/.github/workflows/build-publish.yml
+++ b/.github/workflows/build-publish.yml
@@ -6,7 +6,6 @@ on:
tags:
- "v*"
branches:
- - master
- "release/**"
jobs:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 215b9026620..193a7a5d671 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,9 +2,6 @@ name: "Build Chainlink"
on:
pull_request:
- push:
- branches:
- - master
jobs:
build-chainlink:
diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml
index e625ec50923..0af608624b1 100644
--- a/.github/workflows/changeset.yml
+++ b/.github/workflows/changeset.yml
@@ -8,6 +8,20 @@ on: pull_request
jobs:
changeset:
+ env:
+ TAGS: |
+ - `#added` For any new functionality added.
+ - `#breaking_change` For any functionality that requires manual action for the node to boot.
+ - `#bugfix` For bug fixes.
+ - `#changed` For any change to the existing functionality.
+ - `#db_update` For any feature that introduces updates to database schema.
+ - `#deprecation_notice` For any upcoming deprecation functionality.
+ - `#internal` For changesets that need to be excluded from the final changelog.
+ - `#nops` For any feature that is NOP facing and needs to be in the official Release Notes for the release.
+ - `#removed` For any functionality/config that is removed.
+ - `#updated` For any functionality that is updated.
+ - `#wip` For any change that is not ready yet and external communication about it should be held off till it is feature complete.
+
# For security reasons, GITHUB_TOKEN is read-only on forks, so we cannot leave comments on PRs.
# This check skips the job if it is detected we are running on a fork.
if: ${{ github.event.pull_request.head.repo.full_name == 'smartcontractkit/chainlink' }}
@@ -16,11 +30,13 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
+
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: files-changed
with:
token: ${{ secrets.GITHUB_TOKEN }}
predicate-quantifier: every
+ list-files: shell
filters: |
shared:
- common/**
@@ -41,15 +57,19 @@ jobs:
- added: '.changeset/**'
contracts-changeset:
- added: 'contracts/.changeset/**'
+
- name: Make a comment
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0
if: ${{ (steps.files-changed.outputs.core == 'true' || steps.files-changed.outputs.shared == 'true') && steps.files-changed.outputs.core-changeset == 'false' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
- message: "I see you updated files related to `core`. Please run `pnpm changeset` in the root directory to add a changeset."
+ message: |
+ I see you updated files related to `core`. Please run `pnpm changeset` in the root directory to add a changeset as well as in the text include at least one of the following tags:
+ ${{ env.TAGS }}
reactions: eyes
comment_tag: changeset-core
+
- name: Make a comment
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0
if: ${{ steps.files-changed.outputs.contracts == 'true' && steps.files-changed.outputs.contracts-changeset == 'false' }}
@@ -60,18 +80,46 @@ jobs:
I see you updated files related to `contracts`. Please run `pnpm changeset` in the `contracts` directory to add a changeset.
reactions: eyes
comment_tag: changeset-contracts
+
- name: Check for new changeset for core
if: ${{ (steps.files-changed.outputs.core == 'true' || steps.files-changed.outputs.shared == 'true') && steps.files-changed.outputs.core-changeset == 'false' }}
shell: bash
run: |
- echo "Please run pnpm changeset to add a changeset for core."
+ echo "Please run pnpm changeset to add a changeset for core and include in the text at least one tag."
exit 1
+
- name: Check for new changeset for contracts
if: ${{ steps.files-changed.outputs.contracts == 'true' && steps.files-changed.outputs.contracts-changeset == 'false' }}
shell: bash
run: |
echo "Please run pnpm changeset to add a changeset for contracts."
exit 1
+
+ - name: Check for changeset tags for core
+ id: changeset-tags
+ if: ${{ steps.files-changed.outputs.core-changeset == 'true' }}
+ shell: bash
+ run: bash ./.github/scripts/check-changeset-tags.sh ${{ steps.files-changed.outputs.core-changeset_files }}
+
+ - name: Make a comment
+ uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0
+ if: ${{ steps.files-changed.outputs.core-changeset == 'true' && steps.changeset-tags.outputs.has_tags == 'false' }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ message: |
+ I see you added a changeset file but it does not contain a tag. Please edit the text include at least one of the following tags:
+ ${{ env.TAGS }}
+ reactions: eyes
+ comment_tag: changeset-core-tags
+
+ - name: Check for new changeset tags for core
+ if: ${{ steps.files-changed.outputs.core-changeset == 'true' && steps.changeset-tags.outputs.has_tags == 'false' }}
+ shell: bash
+ run: |
+ echo "Please include at least one tag in the core changeset file"
+ exit 1
+
- name: Collect Metrics
if: always()
id: collect-gha-metrics
diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml
index 9684b27955c..c97af329639 100644
--- a/.github/workflows/ci-core.yml
+++ b/.github/workflows/ci-core.yml
@@ -9,7 +9,6 @@ concurrency:
on:
push:
branches:
- - master
- develop
- "release/*"
merge_group:
@@ -19,7 +18,7 @@ on:
workflow_dispatch:
inputs:
distinct_run_name:
- description: 'A unique identifier for this run, used when running from other repos'
+ description: "A unique identifier for this run, used when running from other repos"
required: false
type: string
evm-ref:
@@ -29,7 +28,6 @@ on:
type: string
jobs:
-
filter: # No need to run core tests if there are only changes to the integration-tests
name: Detect Changes
permissions:
@@ -65,6 +63,7 @@ jobs:
uses: ./.github/actions/golangci-lint
if: ${{ needs.filter.outputs.changes == 'true' }}
with:
+ id: core
gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }}
gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }}
gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }}
@@ -109,6 +108,8 @@ jobs:
- name: Setup Go
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-go
+ - name: Run short tests
+ run: go test -short ./...
- name: Setup Solana
if: ${{ needs.filter.outputs.changes == 'true' }}
uses: ./.github/actions/setup-solana
@@ -211,7 +212,7 @@ jobs:
needs: [filter, core]
name: Flakey Test Detection
runs-on: ubuntu-latest
- if: ${{ always() && github.actor != 'dependabot[bot]' }}
+ if: ${{ always() && github.actor != 'dependabot[bot]' }}
env:
CL_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable
steps:
@@ -234,7 +235,7 @@ jobs:
- name: Touching core/web/assets/index.html
if: ${{ needs.filter.outputs.changes == 'true' }}
run: mkdir -p core/web/assets && touch core/web/assets/index.html
- - name: Download Go vendor packages
+ - name: Download Go vendor packages
if: ${{ needs.filter.outputs.changes == 'true' }}
run: go mod download
- name: Replace chainlink-evm deps
diff --git a/.github/workflows/ci-scripts.yml b/.github/workflows/ci-scripts.yml
index 78c26ff258e..814c354cfe6 100644
--- a/.github/workflows/ci-scripts.yml
+++ b/.github/workflows/ci-scripts.yml
@@ -13,6 +13,7 @@ jobs:
- name: Golang Lint
uses: ./.github/actions/golangci-lint
with:
+ id: scripts
name: lint-scripts
go-directory: core/scripts
go-version-file: core/scripts/go.mod
diff --git a/.github/workflows/cicd-changesets.yml b/.github/workflows/cicd-changesets.yml
index 946ac13a1dd..0bfec7b22f2 100644
--- a/.github/workflows/cicd-changesets.yml
+++ b/.github/workflows/cicd-changesets.yml
@@ -17,7 +17,19 @@ jobs:
id-token: write
contents: read
steps:
+ - name: Checkout repository
+ uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
+
+ - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
+ id: changeset-added
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ filters: |
+ core-changeset:
+ - added: '.changeset/**'
+
- name: cicd-changesets
+ if: steps.changeset-added.outputs.core-changeset == 'true'
uses: smartcontractkit/.github/actions/cicd-changesets@6da79c7b9f14bec077df2c1ad40d53823b409d9c # cicd-changesets@0.3.3
with:
# general inputs
diff --git a/.github/workflows/goreleaser-build-publish-develop.yml b/.github/workflows/goreleaser-build-publish-develop.yml
index a7289a2d66b..b7fe09f35b2 100644
--- a/.github/workflows/goreleaser-build-publish-develop.yml
+++ b/.github/workflows/goreleaser-build-publish-develop.yml
@@ -25,6 +25,8 @@ jobs:
role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_ARN }}
role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }}
aws-region: ${{ secrets.AWS_REGION }}
+ mask-aws-account-id: true
+ role-session-name: goreleaser-build-publish-chainlink.push-develop
- name: Build, sign, and publish image
id: build-sign-publish
uses: ./.github/actions/goreleaser-build-sign-publish
diff --git a/.github/workflows/helm-chart-publish.yml b/.github/workflows/helm-chart-publish.yml
index d85e842f1db..927ed4b0166 100644
--- a/.github/workflows/helm-chart-publish.yml
+++ b/.github/workflows/helm-chart-publish.yml
@@ -20,10 +20,12 @@ jobs:
role-to-assume: ${{ secrets.AWS_ROLE_ARN_GATI }}
role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }}
aws-region: ${{ secrets.AWS_REGION }}
+ mask-aws-account-id: true
+ role-session-name: helm-publish.helm-release
- name: Get Github Token
id: get-gh-token
- uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11
+ uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@5874ff7211cf5a5a2670bb010fbff914eaaae138 # v2.3.12
with:
url: ${{ secrets.GATI_LAMBDA_FUNCTION_URL }}
diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml
index 1386bfef8f3..98d67a8b2d3 100644
--- a/.github/workflows/integration-tests.yml
+++ b/.github/workflows/integration-tests.yml
@@ -379,6 +379,7 @@ jobs:
cl_repo: ${{ env.CHAINLINK_IMAGE }}
cl_image_tag: ${{ inputs.evm-ref || github.sha }}
aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
+ artifacts_name: ${{ matrix.product.name }}-test-logs
artifacts_location: |
./integration-tests/smoke/logs/
/tmp/gotest.log
@@ -470,6 +471,7 @@ jobs:
cl_repo: ${{ env.CHAINLINK_IMAGE }}
cl_image_tag: ${{ inputs.evm-ref || github.sha }}
aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
+ artifacts_name: ${{ matrix.product.name }}-test-logs
artifacts_location: |
./integration-tests/smoke/logs/
/tmp/gotest.log
@@ -854,6 +856,7 @@ jobs:
test_download_vendor_packages_command: cd ./integration-tests && go mod download
cl_repo: ${{ env.CHAINLINK_IMAGE }}
cl_image_tag: ${{ steps.get_latest_version.outputs.latest_version }}
+ artifacts_name: node-migration-test-logs
artifacts_location: |
./integration-tests/migration/logs
/tmp/gotest.log
@@ -865,14 +868,6 @@ jobs:
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
- - name: Upload test log
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
- if: failure()
- with:
- name: test-log-${{ matrix.product.name }}
- path: /tmp/gotest.log
- retention-days: 7
- continue-on-error: true
- name: Collect Metrics
if: always()
id: collect-gha-metrics
@@ -1160,21 +1155,17 @@ jobs:
test_command_to_run: export ENV_JOB_IMAGE=${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-solana-tests:${{ needs.get_solana_sha.outputs.sha }} && make test_smoke
cl_repo: ${{ env.CHAINLINK_IMAGE }}
cl_image_tag: ${{ inputs.evm-ref || github.sha }}
- artifacts_location: /home/runner/work/chainlink-solana/chainlink-solana/integration-tests/logs
publish_check_name: Solana Smoke Test Results
go_mod_path: ./integration-tests/go.mod
cache_key_id: core-solana-e2e-${{ env.MOD_CACHE_VERSION }}
token: ${{ secrets.GITHUB_TOKEN }}
aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
+ artifacts_name: solana-test-logs
+ artifacts_location: |
+ ./integration-tests/smoke/logs
+ /tmp/gotest.log
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_KUBECONFIG: ""
run_setup: false
- - name: Upload test log
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
- if: failure()
- with:
- name: test-log-solana
- path: /tmp/gotest.log
- retention-days: 7
- continue-on-error: true
+
diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml
index 860120972d5..f520e2307d9 100644
--- a/.github/workflows/on-demand-vrfv2-performance-test.yml
+++ b/.github/workflows/on-demand-vrfv2-performance-test.yml
@@ -15,6 +15,10 @@ on:
- "Load"
- "Stress"
- "Spike"
+ test_list_regex:
+ description: "Regex for tests to run"
+ required: false
+ default: "(TestVRFV2Performance)"
jobs:
vrfv2_performance_test:
name: VRFV2 Performance Test
@@ -71,7 +75,7 @@ jobs:
- name: Run Tests
uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11
with:
- test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run TestVRFV2Performance ./vrfv2
+ test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2
test_download_vendor_packages_command: cd ./integration-tests && go mod download
cl_repo: ${{ env.CHAINLINK_IMAGE }}
cl_image_tag: ${{ env.CHAINLINK_VERSION }}
diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml
index 463a7512b0c..16d37617a68 100644
--- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml
+++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml
@@ -14,8 +14,11 @@ on:
- "Soak"
- "Load"
- "Stress"
- - "Spike"
-
+ - "Spike"
+ test_list_regex:
+ description: "Regex for tests to run"
+ required: false
+ default: "(TestVRFV2PlusPerformance)"
jobs:
vrfv2plus_performance_test:
name: VRFV2 Plus Performance Test
@@ -72,7 +75,7 @@ jobs:
- name: Run Tests
uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11
with:
- test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run TestVRFV2PlusPerformance ./vrfv2plus
+ test_command_to_run: cd ./integration-tests/load && go test -v -count=1 -timeout 24h -run "${{ inputs.test_list_regex }}" ./vrfv2plus
test_download_vendor_packages_command: cd ./integration-tests && go mod download
cl_repo: ${{ env.CHAINLINK_IMAGE }}
cl_image_tag: ${{ env.CHAINLINK_VERSION }}
diff --git a/.github/workflows/operator-ui-ci.yml b/.github/workflows/operator-ui-ci.yml
index 6f6663478fe..b67eb2c35f7 100644
--- a/.github/workflows/operator-ui-ci.yml
+++ b/.github/workflows/operator-ui-ci.yml
@@ -31,13 +31,14 @@ jobs:
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{ secrets.AWS_OIDC_CHAINLINK_CI_OPERATOR_UI_ACCESS_TOKEN_ISSUER_ROLE_ARN }}
+ aws-region: ${{ secrets.AWS_REGION }}
role-duration-seconds: 3600
role-session-name: operator-ui-ci.check-gql
- aws-region: ${{ secrets.AWS_REGION }}
+ mask-aws-account-id: true
- name: Get Github Token
id: get-gh-token
- uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11
+ uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@5874ff7211cf5a5a2670bb010fbff914eaaae138 # v2.3.12
with:
url: ${{ secrets.AWS_INFRA_RELENG_TOKEN_ISSUER_LAMBDA_URL }}
diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml
index ee12102f3dd..30b2a302e79 100644
--- a/.github/workflows/pr-labels.yml
+++ b/.github/workflows/pr-labels.yml
@@ -34,9 +34,10 @@ jobs:
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{ secrets.AWS_OIDC_CRIB_ROLE_ARN_SAND }}
- role-duration-seconds: 900
- role-session-name: gha-pr-labels-crib
aws-region: ${{ secrets.AWS_REGION }}
+ role-duration-seconds: 900
+ mask-aws-account-id: true
+ role-session-name: pr-labels.crib
- name: Comment CRIB details on PR
run: ./.github/scripts/crib/pr-comment-crib-env.js
diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml
index cea16f45f16..2d62ef864a5 100644
--- a/.github/workflows/solidity-foundry.yml
+++ b/.github/workflows/solidity-foundry.yml
@@ -79,7 +79,7 @@ jobs:
FOUNDRY_PROFILE: ${{ matrix.product }}
- name: Run Forge snapshot
- if: ${{ !contains(fromJson('["vrf"]'), matrix.product) && !contains(fromJson('["automation"]'), matrix.product) && needs.changes.outputs.changes == 'true' }}
+ if: ${{ !contains(fromJson('["vrf"]'), matrix.product) && !contains(fromJson('["automation"]'), matrix.product) && !contains(fromJson('["keystone"]'), matrix.product) && needs.changes.outputs.changes == 'true' }}
run: |
forge snapshot --nmt "testFuzz_\w{1,}?" --check gas-snapshots/${{ matrix.product }}.gas-snapshot
id: snapshot
diff --git a/.gitignore b/.gitignore
index ccf8a006e7b..7d07300311f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -97,3 +97,5 @@ override*.toml
# Pythin venv
.venv/
+
+ocr_soak_report.csv
\ No newline at end of file
diff --git a/CODEOWNERS b/CODEOWNERS
index 65f0b58753f..8741cb7a685 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -75,7 +75,7 @@ core/scripts/gateway @smartcontractkit/functions
/contracts/src/v0.8/l2ep @chris-de-leon-cll
/contracts/src/v0.8/llo-feeds @smartcontractkit/mercury-team
# TODO: mocks folder, folder should be removed and files moved to the correct folders
-/contracts/src/v0.8/operatorforwarder @RensR
+/contracts/src/v0.8/operatorforwarder @austinborn
/contracts/src/v0.8/shared @RensR
# TODO: tests folder, folder should be removed and files moved to the correct folders
# TODO: transmission folder, owner should be found
diff --git a/GNUmakefile b/GNUmakefile
index 34a75b77984..10d72cb724c 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -35,11 +35,11 @@ gomodtidy: ## Run go mod tidy on all modules.
cd ./dashboard-lib && go mod tidy
cd ./charts/chainlink-cluster && go mod tidy
-.PHONY: godoc
-godoc: ## Install and run godoc
- go install golang.org/x/tools/cmd/godoc@latest
- # http://localhost:6060/pkg/github.com/smartcontractkit/chainlink/v2/
- godoc -http=:6060
+.PHONY: docs
+docs: ## Install and run pkgsite to view Go docs
+ go install golang.org/x/pkgsite/cmd/pkgsite@latest
+ # http://localhost:8080/pkg/github.com/smartcontractkit/chainlink/v2/
+ pkgsite
.PHONY: install-chainlink
install-chainlink: operator-ui ## Install the chainlink binary.
diff --git a/README.md b/README.md
index 0d336dd22b3..167fae4adee 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ regarding Chainlink social accounts, news, and networking.
2. Install [NodeJS v16](https://nodejs.org/en/download/package-manager/) & [pnpm via npm](https://pnpm.io/installation#using-npm).
- It might be easier long term to use [nvm](https://nodejs.org/en/download/package-manager/#nvm) to switch between node versions for different projects. For example, assuming $NODE_VERSION was set to a valid version of NodeJS, you could run: `nvm install $NODE_VERSION && nvm use $NODE_VERSION`
3. Install [Postgres (>= 12.x)](https://wiki.postgresql.org/wiki/Detailed_installation_guides). It is recommended to run the latest major version of postgres.
- - Note if you are running the official Chainlink docker image, the highest supported Postgres version is 15.x due to the bundled client.
+ - Note if you are running the official Chainlink docker image, the highest supported Postgres version is 16.x due to the bundled client.
- You should [configure Postgres](https://www.postgresql.org/docs/current/ssl-tcp.html) to use SSL connection (or for testing you can set `?sslmode=disable` in your Postgres query string).
4. Ensure you have Python 3 installed (this is required by [solc-select](https://github.com/crytic/solc-select) which is needed to compile solidity contracts)
5. Download Chainlink: `git clone https://github.com/smartcontractkit/chainlink && cd chainlink`
diff --git a/charts/chainlink-cluster/README.md b/charts/chainlink-cluster/README.md
index 0fbbd5d16df..a0a4b8a78cc 100644
--- a/charts/chainlink-cluster/README.md
+++ b/charts/chainlink-cluster/README.md
@@ -151,6 +151,9 @@ We are using [Grabana](https://github.com/K-Phoen/grabana) lib to create dashboa
You can also select dashboard platform in `INFRA_PLATFORM` either `kubernetes` or `docker`
+You can select the dashboard panels with `PANELS_INCLUDED` which is a list of panel names separated by comma
+If you don't specify it will include core panels by default
+
```
export LOKI_TENANT_ID=promtail
export LOKI_URL=...
@@ -159,7 +162,7 @@ export GRAFANA_TOKEN=...
export PROMETHEUS_DATA_SOURCE_NAME=Thanos
export LOKI_DATA_SOURCE_NAME=Loki
export INFRA_PLATFORM=kubernetes
-export GRAFANA_FOLDER=CRIB
+export GRAFANA_FOLDER=DashboardCoreDebug
export DASHBOARD_NAME=CL-Cluster
devspace run dashboard_deploy
diff --git a/charts/chainlink-cluster/dashboard/cmd/delete.go b/charts/chainlink-cluster/dashboard/cmd/delete.go
new file mode 100644
index 00000000000..45b4b11d67f
--- /dev/null
+++ b/charts/chainlink-cluster/dashboard/cmd/delete.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+ lib "github.com/smartcontractkit/chainlink/dashboard-lib"
+)
+
+func main() {
+ cfg := lib.ReadEnvDeployOpts()
+ db := lib.NewDashboard(cfg.Name, cfg, nil)
+ err := db.Delete()
+ if err != nil {
+ lib.L.Fatal().Err(err).Msg("failed to delete the dashboard")
+ }
+ lib.L.Info().
+ Str("Name", db.Name).
+ Str("GrafanaURL", db.DeployOpts.GrafanaURL).
+ Str("GrafanaFolder", db.DeployOpts.GrafanaFolder).
+ Msg("Dashboard deleted")
+}
diff --git a/charts/chainlink-cluster/dashboard/cmd/deploy.go b/charts/chainlink-cluster/dashboard/cmd/deploy.go
index 883c1939a6b..24c3af4589b 100644
--- a/charts/chainlink-cluster/dashboard/cmd/deploy.go
+++ b/charts/chainlink-cluster/dashboard/cmd/deploy.go
@@ -3,31 +3,48 @@ package main
import (
"github.com/K-Phoen/grabana/dashboard"
lib "github.com/smartcontractkit/chainlink/dashboard-lib"
+ atlas_don "github.com/smartcontractkit/chainlink/dashboard-lib/atlas-don"
core_don "github.com/smartcontractkit/chainlink/dashboard-lib/core-don"
k8spods "github.com/smartcontractkit/chainlink/dashboard-lib/k8s-pods"
waspdb "github.com/smartcontractkit/wasp/dashboard"
-)
-
-const (
- DashboardName = "Chainlink Cluster (DON)"
+ "strings"
)
func main() {
cfg := lib.ReadEnvDeployOpts()
- db := lib.NewDashboard(DashboardName, cfg,
+ db := lib.NewDashboard(cfg.Name, cfg,
[]dashboard.Option{
dashboard.AutoRefresh("10s"),
dashboard.Tags([]string{"generated"}),
},
)
- db.Add(
- core_don.New(
- core_don.Props{
- PrometheusDataSource: cfg.DataSources.Prometheus,
- PlatformOpts: core_don.PlatformPanelOpts(cfg.Platform),
- },
- ),
- )
+ if len(cfg.PanelsIncluded) == 0 || cfg.PanelsIncluded["core"] {
+ db.Add(
+ core_don.New(
+ core_don.Props{
+ PrometheusDataSource: cfg.DataSources.Prometheus,
+ PlatformOpts: core_don.PlatformPanelOpts(cfg.Platform),
+ },
+ ),
+ )
+ // TODO: refactor as a component later
+ addWASPRows(db, cfg)
+ }
+ if cfg.PanelsIncluded["ocr"] || cfg.PanelsIncluded["ocr2"] || cfg.PanelsIncluded["ocr3"] {
+ for key := range cfg.PanelsIncluded {
+ if strings.Contains(key, "ocr") {
+ db.Add(
+ atlas_don.New(
+ atlas_don.Props{
+ PrometheusDataSource: cfg.DataSources.Prometheus,
+ PlatformOpts: atlas_don.PlatformPanelOpts(cfg.Platform, key),
+ OcrVersion: key,
+ },
+ ),
+ )
+ }
+ }
+ }
if cfg.Platform == "kubernetes" {
db.Add(
k8spods.New(
@@ -38,13 +55,11 @@ func main() {
),
)
}
- // TODO: refactor as a component later
- addWASPRows(db, cfg)
if err := db.Deploy(); err != nil {
lib.L.Fatal().Err(err).Msg("failed to deploy the dashboard")
}
lib.L.Info().
- Str("Name", DashboardName).
+ Str("Name", db.Name).
Str("GrafanaURL", db.DeployOpts.GrafanaURL).
Str("GrafanaFolder", db.DeployOpts.GrafanaFolder).
Msg("Dashboard deployed")
diff --git a/charts/chainlink-cluster/templates/chainlink-cm.yaml b/charts/chainlink-cluster/templates/chainlink-cm.yaml
index 6f8b043e3d1..9a99e2a5128 100644
--- a/charts/chainlink-cluster/templates/chainlink-cm.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-cm.yaml
@@ -1,3 +1,4 @@
+{{- if .Values.chainlink.enabled }}
{{- range $cfg := .Values.chainlink.nodes }}
apiVersion: v1
kind: ConfigMap
@@ -69,3 +70,4 @@ data:
{{ end }}
---
{{- end }}
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/chainlink-db-deployment.yaml b/charts/chainlink-cluster/templates/chainlink-db-deployment.yaml
index ba72c5ff8fb..0ca7c4afd71 100644
--- a/charts/chainlink-cluster/templates/chainlink-db-deployment.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-db-deployment.yaml
@@ -1,3 +1,4 @@
+{{- if .Values.db.enabled }}
{{- range $cfg := .Values.chainlink.nodes }}
apiVersion: apps/v1
{{ if $.Values.db.stateful }}
@@ -150,3 +151,4 @@ spec:
{{- end }}
---
{{- end }}
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/chainlink-db-networkpolicy.yaml b/charts/chainlink-cluster/templates/chainlink-db-networkpolicy.yaml
index 3e4c9f49b46..53664884f26 100644
--- a/charts/chainlink-cluster/templates/chainlink-db-networkpolicy.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-db-networkpolicy.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.networkPolicies.enabled }}
+{{- if and .Values.db.enabled .Values.networkPolicies.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
@@ -18,4 +18,4 @@ spec:
ports:
- protocol: TCP
port: 5432
-{{- end }}
\ No newline at end of file
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/chainlink-db-service.yaml b/charts/chainlink-cluster/templates/chainlink-db-service.yaml
index f27bd9eab20..5ed7d0ca4dd 100644
--- a/charts/chainlink-cluster/templates/chainlink-db-service.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-db-service.yaml
@@ -1,3 +1,4 @@
+{{- if .Values.db.enabled }}
{{- range $cfg := .Values.chainlink.nodes }}
apiVersion: v1
kind: Service
@@ -13,4 +14,5 @@ spec:
port: 5432
targetPort: 5432
---
-{{- end }}
\ No newline at end of file
+{{- end }}
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/chainlink-node-deployment.yaml b/charts/chainlink-cluster/templates/chainlink-node-deployment.yaml
index 38676716f90..e91a400967a 100644
--- a/charts/chainlink-cluster/templates/chainlink-node-deployment.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-node-deployment.yaml
@@ -1,3 +1,4 @@
+{{- if .Values.chainlink.enabled }}
{{- range $index, $cfg := .Values.chainlink.nodes }}
apiVersion: apps/v1
kind: Deployment
@@ -126,3 +127,4 @@ spec:
{{- end }}
---
{{- end }}
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/chainlink-node-networkpolicy.yaml b/charts/chainlink-cluster/templates/chainlink-node-networkpolicy.yaml
index f2d0c02676e..8f465288767 100644
--- a/charts/chainlink-cluster/templates/chainlink-node-networkpolicy.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-node-networkpolicy.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.networkPolicies.enabled }}
+{{- if and .Values.chainlink.enabled .Values.networkPolicies.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
@@ -15,4 +15,4 @@ spec:
- podSelector:
matchLabels:
app: {{ $.Release.Name }}
-{{- end }}
\ No newline at end of file
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/chainlink-node-service.yaml b/charts/chainlink-cluster/templates/chainlink-node-service.yaml
index 7a3b70efb4f..71b9ca498d2 100644
--- a/charts/chainlink-cluster/templates/chainlink-node-service.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-node-service.yaml
@@ -1,3 +1,4 @@
+{{- if .Values.chainlink.enabled }}
{{- range $cfg := .Values.chainlink.nodes }}
apiVersion: v1
kind: Service
@@ -15,4 +16,5 @@ spec:
instance: {{ $cfg.name }}
type: ClusterIP
---
-{{- end }}
\ No newline at end of file
+{{- end }}
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/chainlink-pod-monitor.yaml b/charts/chainlink-cluster/templates/chainlink-pod-monitor.yaml
index 05852642a29..bb8c5d2b1a6 100644
--- a/charts/chainlink-cluster/templates/chainlink-pod-monitor.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-pod-monitor.yaml
@@ -1,4 +1,4 @@
-{{- if $.Values.prometheusMonitor }}
+{{- if and .Values.chainlink.enabled .Values.prometheusMonitor }}
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
diff --git a/charts/chainlink-cluster/templates/chainlink-secret.yaml b/charts/chainlink-cluster/templates/chainlink-secret.yaml
index 3502c12ecfd..f0531b16511 100644
--- a/charts/chainlink-cluster/templates/chainlink-secret.yaml
+++ b/charts/chainlink-cluster/templates/chainlink-secret.yaml
@@ -1,3 +1,4 @@
+{{- if .Values.chainlink.enabled }}
{{- range $cfg := .Values.chainlink.nodes }}
apiVersion: v1
kind: Secret
@@ -9,4 +10,5 @@ data:
apicredentials: bm90cmVhbEBmYWtlZW1haWwuY2hudHdvY2hhaW5zCg==
node-password: VC50TEhrY213ZVBUL3AsXXNZdW50andIS0FzcmhtIzRlUnM0THVLSHd2SGVqV1lBQzJKUDRNOEhpbXdnbWJhWgo=
---
-{{- end }}
\ No newline at end of file
+{{- end }}
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/geth-config-map.yaml b/charts/chainlink-cluster/templates/geth-config-map.yaml
index 0d9abb042e3..6a5f4bacc0d 100644
--- a/charts/chainlink-cluster/templates/geth-config-map.yaml
+++ b/charts/chainlink-cluster/templates/geth-config-map.yaml
@@ -1,4 +1,4 @@
-{{ if (hasKey .Values "geth") }}
+{{ if and (hasKey .Values "geth") .Values.geth.enabled }}
{{- range $cfg := .Values.geth.chains }}
apiVersion: v1
kind: ConfigMap
@@ -152,4 +152,4 @@ data:
}
---
{{- end }}
-{{ end }}
\ No newline at end of file
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/geth-deployment.yaml b/charts/chainlink-cluster/templates/geth-deployment.yaml
index e8e04936ea4..6eccdbd20b4 100644
--- a/charts/chainlink-cluster/templates/geth-deployment.yaml
+++ b/charts/chainlink-cluster/templates/geth-deployment.yaml
@@ -1,4 +1,4 @@
-{{ if (hasKey .Values "geth") }}
+{{ if and (hasKey .Values "geth") .Values.geth.enabled }}
{{- range $cfg := .Values.geth.chains }}
apiVersion: apps/v1
kind: Deployment
@@ -127,4 +127,4 @@ spec:
{{- end }}
---
{{- end }}
-{{ end }}
\ No newline at end of file
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/geth-networkpolicy.yaml b/charts/chainlink-cluster/templates/geth-networkpolicy.yaml
index 9e823a0431b..2a37a92aaaa 100644
--- a/charts/chainlink-cluster/templates/geth-networkpolicy.yaml
+++ b/charts/chainlink-cluster/templates/geth-networkpolicy.yaml
@@ -1,3 +1,4 @@
+{{ if and (hasKey .Values "geth") .Values.geth.enabled }}
{{- if .Values.networkPolicies.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
@@ -20,4 +21,5 @@ spec:
port: 8544
- protocol: TCP
port: 8546
-{{- end }}
\ No newline at end of file
+{{- end }}
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/geth-service.yaml b/charts/chainlink-cluster/templates/geth-service.yaml
index 3016c53048f..63a86a3d1d7 100644
--- a/charts/chainlink-cluster/templates/geth-service.yaml
+++ b/charts/chainlink-cluster/templates/geth-service.yaml
@@ -1,4 +1,4 @@
-{{ if (hasKey .Values "geth") }}
+{{ if and (hasKey .Values "geth") .Values.geth.enabled }}
{{- range $cfg := .Values.geth.chains }}
apiVersion: v1
kind: Service
@@ -18,4 +18,4 @@ spec:
type: ClusterIP
---
{{- end }}
-{{ end }}
\ No newline at end of file
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/mockserver-networkpolicy.yaml b/charts/chainlink-cluster/templates/mockserver-networkpolicy.yaml
index 8d167b4f924..0fa48dcfc41 100644
--- a/charts/chainlink-cluster/templates/mockserver-networkpolicy.yaml
+++ b/charts/chainlink-cluster/templates/mockserver-networkpolicy.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.networkPolicies.enabled }}
+{{- if and .Values.mockserver.enabled .Values.networkPolicies.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
@@ -18,4 +18,4 @@ spec:
ports:
- protocol: TCP
port: 1080
-{{- end }}
\ No newline at end of file
+{{- end }}
diff --git a/charts/chainlink-cluster/templates/networkpolicy-default.yaml b/charts/chainlink-cluster/templates/networkpolicy-default.yaml
index a2cc23ed7f9..10927c26eb6 100644
--- a/charts/chainlink-cluster/templates/networkpolicy-default.yaml
+++ b/charts/chainlink-cluster/templates/networkpolicy-default.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.networkPolicies.enabled }}
+{{- if and .Values.mockserver.enabled .Values.networkPolicies.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
diff --git a/charts/chainlink-cluster/values.yaml b/charts/chainlink-cluster/values.yaml
index d3c1c384a2b..ed497a65ff9 100644
--- a/charts/chainlink-cluster/values.yaml
+++ b/charts/chainlink-cluster/values.yaml
@@ -10,6 +10,7 @@
# image: ethereum/client-go
# version: stable
chainlink:
+ enabled: true
podSecurityContext:
fsGroup: 14933
securityContext:
@@ -88,6 +89,7 @@ chainlink:
#
# if you are running long tests
db:
+ enabled: true
podSecurityContext:
fsGroup: 999
securityContext:
@@ -109,6 +111,7 @@ db:
memory: 1024Mi
# default cluster shipped with latest Geth ( dev mode by default )
geth:
+ enabled: true
podSecurityContext:
fsGroup: 999
securityContext:
diff --git a/common/chains/label/label.go b/common/chains/label/label.go
deleted file mode 100644
index 2498fde0ee9..00000000000
--- a/common/chains/label/label.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package label
-
-const (
- MaxInFlightTransactionsWarning = `WARNING: If this happens a lot, you may need to increase Transactions.MaxInFlight to boost your node's transaction throughput, however you do this at your own risk. You MUST first ensure your node is configured not to ever evict local transactions that exceed this number otherwise the node can get permanently stuck. See the performance guide for more details: https://docs.chain.link/docs/evm-performance-configuration/`
- MaxQueuedTransactionsWarning = `WARNING: Hitting Transactions.MaxQueued is a sanity limit and should never happen under normal operation. Unless you are operating with very high throughput, this error is unlikely to be a problem with your Chainlink node configuration, and instead more likely to be caused by a problem with your node's connectivity. Check your node: it may not be broadcasting transactions to the network, or it might be overloaded and evicting Chainlink's transactions from its mempool. It is recommended to run Chainlink with multiple primary and sendonly nodes for redundancy and to ensure fast and reliable transaction propagation. Increasing Transactions.MaxQueued will allow Chainlink to buffer more unsent transactions, but you should only do this if you need very high burst transmission rates. If you don't need very high burst throughput, increasing this limit is not the correct action to take here and will probably make things worse. See the performance guide for more details: https://docs.chain.link/docs/evm-performance-configuration/`
- NodeConnectivityProblemWarning = `WARNING: If this happens a lot, it may be a sign that your node has a connectivity problem, and your transactions are not making it to any miners. It is recommended to run Chainlink with multiple primary and sendonly nodes for redundancy and to ensure fast and reliable transaction propagation. See the performance guide for more details: https://docs.chain.link/docs/evm-performance-configuration/`
- RPCTxFeeCapConfiguredIncorrectlyWarning = `WARNING: Gas price was rejected by the node for being too high. By default, go-ethereum (and clones) have a built-in upper limit for gas price. It is preferable to disable this and rely Chainlink's internal gas limits instead. Your RPC node's RPCTxFeeCap needs to be disabled or increased (recommended configuration: --rpc.gascap=0 --rpc.txfeecap=0). If you want to limit Chainlink's max gas price, you may do so by setting GasEstimator.PriceMax on the Chainlink node. Chainlink will never send a transaction with a total cost higher than GasEstimator.PriceMax. See the performance guide for more details: https://docs.chain.link/docs/evm-performance-configuration/`
-)
diff --git a/common/fee/models.go b/common/fee/models.go
index ff397fd2f9f..0568a2f1433 100644
--- a/common/fee/models.go
+++ b/common/fee/models.go
@@ -5,9 +5,9 @@ import (
"fmt"
"math/big"
+ "github.com/smartcontractkit/chainlink-common/pkg/chains/label"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
bigmath "github.com/smartcontractkit/chainlink-common/pkg/utils/big_math"
- "github.com/smartcontractkit/chainlink/v2/common/chains/label"
)
var (
diff --git a/common/headtracker/head_broadcaster.go b/common/headtracker/head_broadcaster.go
index 758a7713846..b20bb1993bd 100644
--- a/common/headtracker/head_broadcaster.go
+++ b/common/headtracker/head_broadcaster.go
@@ -16,17 +16,34 @@ import (
const TrackableCallbackTimeout = 2 * time.Second
-type callbackSet[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] map[int]types.HeadTrackable[H, BLOCK_HASH]
+type callbackSet[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] map[int]HeadTrackable[H, BLOCK_HASH]
-func (set callbackSet[H, BLOCK_HASH]) values() []types.HeadTrackable[H, BLOCK_HASH] {
- var values []types.HeadTrackable[H, BLOCK_HASH]
+func (set callbackSet[H, BLOCK_HASH]) values() []HeadTrackable[H, BLOCK_HASH] {
+ var values []HeadTrackable[H, BLOCK_HASH]
for _, callback := range set {
values = append(values, callback)
}
return values
}
-type HeadBroadcaster[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] struct {
+// HeadTrackable is implemented by the core txm to be able to receive head events from any chain.
+// Chain implementations should notify head events to the core txm via this interface.
+//
+//go:generate mockery --quiet --name HeadTrackable --output ./mocks/ --case=underscore
+type HeadTrackable[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] interface {
+ // OnNewLongestChain sends a new head when it becomes available. Subscribers can recursively trace the parent
+ // of the head to the finalized block back.
+ OnNewLongestChain(ctx context.Context, head H)
+}
+
+// HeadBroadcaster relays new Heads to all subscribers.
+type HeadBroadcaster[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] interface {
+ services.Service
+ BroadcastNewLongestChain(H)
+ Subscribe(callback HeadTrackable[H, BLOCK_HASH]) (currentLongestChain H, unsubscribe func())
+}
+
+type headBroadcaster[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] struct {
services.StateMachine
logger logger.Logger
callbacks callbackSet[H, BLOCK_HASH]
@@ -44,8 +61,8 @@ func NewHeadBroadcaster[
BLOCK_HASH types.Hashable,
](
lggr logger.Logger,
-) *HeadBroadcaster[H, BLOCK_HASH] {
- return &HeadBroadcaster[H, BLOCK_HASH]{
+) HeadBroadcaster[H, BLOCK_HASH] {
+ return &headBroadcaster[H, BLOCK_HASH]{
logger: logger.Named(lggr, "HeadBroadcaster"),
callbacks: make(callbackSet[H, BLOCK_HASH]),
mailbox: mailbox.NewSingle[H](),
@@ -53,7 +70,7 @@ func NewHeadBroadcaster[
}
}
-func (hb *HeadBroadcaster[H, BLOCK_HASH]) Start(context.Context) error {
+func (hb *headBroadcaster[H, BLOCK_HASH]) Start(context.Context) error {
return hb.StartOnce("HeadBroadcaster", func() error {
hb.wgDone.Add(1)
go hb.run()
@@ -61,7 +78,7 @@ func (hb *HeadBroadcaster[H, BLOCK_HASH]) Start(context.Context) error {
})
}
-func (hb *HeadBroadcaster[H, BLOCK_HASH]) Close() error {
+func (hb *headBroadcaster[H, BLOCK_HASH]) Close() error {
return hb.StopOnce("HeadBroadcaster", func() error {
hb.mutex.Lock()
// clear all callbacks
@@ -74,21 +91,21 @@ func (hb *HeadBroadcaster[H, BLOCK_HASH]) Close() error {
})
}
-func (hb *HeadBroadcaster[H, BLOCK_HASH]) Name() string {
+func (hb *headBroadcaster[H, BLOCK_HASH]) Name() string {
return hb.logger.Name()
}
-func (hb *HeadBroadcaster[H, BLOCK_HASH]) HealthReport() map[string]error {
+func (hb *headBroadcaster[H, BLOCK_HASH]) HealthReport() map[string]error {
return map[string]error{hb.Name(): hb.Healthy()}
}
-func (hb *HeadBroadcaster[H, BLOCK_HASH]) BroadcastNewLongestChain(head H) {
+func (hb *headBroadcaster[H, BLOCK_HASH]) BroadcastNewLongestChain(head H) {
hb.mailbox.Deliver(head)
}
// Subscribe subscribes to OnNewLongestChain and Connect until HeadBroadcaster is closed,
// or unsubscribe callback is called explicitly
-func (hb *HeadBroadcaster[H, BLOCK_HASH]) Subscribe(callback types.HeadTrackable[H, BLOCK_HASH]) (currentLongestChain H, unsubscribe func()) {
+func (hb *headBroadcaster[H, BLOCK_HASH]) Subscribe(callback HeadTrackable[H, BLOCK_HASH]) (currentLongestChain H, unsubscribe func()) {
hb.mutex.Lock()
defer hb.mutex.Unlock()
@@ -106,7 +123,7 @@ func (hb *HeadBroadcaster[H, BLOCK_HASH]) Subscribe(callback types.HeadTrackable
return
}
-func (hb *HeadBroadcaster[H, BLOCK_HASH]) run() {
+func (hb *headBroadcaster[H, BLOCK_HASH]) run() {
defer hb.wgDone.Done()
for {
@@ -122,7 +139,7 @@ func (hb *HeadBroadcaster[H, BLOCK_HASH]) run() {
// DEV: the head relayer makes no promises about head delivery! Subscribing
// Jobs should expect to the relayer to skip heads if there is a large number of listeners
// and all callbacks cannot be completed in the allotted time.
-func (hb *HeadBroadcaster[H, BLOCK_HASH]) executeCallbacks() {
+func (hb *headBroadcaster[H, BLOCK_HASH]) executeCallbacks() {
head, exists := hb.mailbox.Retrieve()
if !exists {
hb.logger.Info("No head to retrieve. It might have been skipped")
@@ -146,7 +163,7 @@ func (hb *HeadBroadcaster[H, BLOCK_HASH]) executeCallbacks() {
defer cancel()
for _, callback := range callbacks {
- go func(trackable types.HeadTrackable[H, BLOCK_HASH]) {
+ go func(trackable HeadTrackable[H, BLOCK_HASH]) {
defer wg.Done()
start := time.Now()
cctx, cancel := context.WithTimeout(ctx, TrackableCallbackTimeout)
diff --git a/common/headtracker/head_listener.go b/common/headtracker/head_listener.go
index e7ea4fb51ae..15977c4dfe4 100644
--- a/common/headtracker/head_listener.go
+++ b/common/headtracker/head_listener.go
@@ -29,7 +29,26 @@ var (
}, []string{"ChainID"})
)
-type HeadListener[
+// headHandler is a callback that handles incoming heads
+type headHandler[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] func(ctx context.Context, header H) error
+
+// HeadListener is a chain agnostic interface that manages connection of Client that receives heads from the blockchain node
+type HeadListener[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] interface {
+ // ListenForNewHeads kicks off the listen loop (not thread safe)
+ // done() must be executed upon leaving ListenForNewHeads()
+ ListenForNewHeads(handleNewHead headHandler[H, BLOCK_HASH], done func())
+
+ // ReceivingHeads returns true if the listener is receiving heads (thread safe)
+ ReceivingHeads() bool
+
+ // Connected returns true if the listener is connected (thread safe)
+ Connected() bool
+
+ // HealthReport returns report of errors within HeadListener
+ HealthReport() map[string]error
+}
+
+type headListener[
HTH htrktypes.Head[BLOCK_HASH, ID],
S types.Subscription,
ID types.ID,
@@ -56,8 +75,8 @@ func NewHeadListener[
client CLIENT,
config htrktypes.Config,
chStop chan struct{},
-) *HeadListener[HTH, S, ID, BLOCK_HASH] {
- return &HeadListener[HTH, S, ID, BLOCK_HASH]{
+) HeadListener[HTH, BLOCK_HASH] {
+ return &headListener[HTH, S, ID, BLOCK_HASH]{
config: config,
client: client,
logger: logger.Named(lggr, "HeadListener"),
@@ -65,11 +84,11 @@ func NewHeadListener[
}
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) Name() string {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) Name() string {
return hl.logger.Name()
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) ListenForNewHeads(handleNewHead types.NewHeadHandler[HTH, BLOCK_HASH], done func()) {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) ListenForNewHeads(handleNewHead headHandler[HTH, BLOCK_HASH], done func()) {
defer done()
defer hl.unsubscribe()
@@ -91,15 +110,15 @@ func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) ListenForNewHeads(handleNewHead
}
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) ReceivingHeads() bool {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) ReceivingHeads() bool {
return hl.receivingHeads.Load()
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) Connected() bool {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) Connected() bool {
return hl.connected.Load()
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) HealthReport() map[string]error {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) HealthReport() map[string]error {
var err error
if !hl.ReceivingHeads() {
err = errors.New("Listener is not receiving heads")
@@ -110,7 +129,7 @@ func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) HealthReport() map[string]error
return map[string]error{hl.Name(): err}
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) receiveHeaders(ctx context.Context, handleNewHead types.NewHeadHandler[HTH, BLOCK_HASH]) error {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) receiveHeaders(ctx context.Context, handleNewHead headHandler[HTH, BLOCK_HASH]) error {
var noHeadsAlarmC <-chan time.Time
var noHeadsAlarmT *time.Ticker
noHeadsAlarmDuration := hl.config.BlockEmissionIdleWarningThreshold()
@@ -169,7 +188,7 @@ func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) receiveHeaders(ctx context.Conte
}
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) subscribe(ctx context.Context) bool {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) subscribe(ctx context.Context) bool {
subscribeRetryBackoff := utils.NewRedialBackoff()
chainId := hl.client.ConfiguredChainID()
@@ -196,7 +215,7 @@ func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) subscribe(ctx context.Context) b
}
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) subscribeToHead(ctx context.Context) error {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) subscribeToHead(ctx context.Context) error {
hl.chHeaders = make(chan HTH)
var err error
@@ -211,7 +230,7 @@ func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) subscribeToHead(ctx context.Cont
return nil
}
-func (hl *HeadListener[HTH, S, ID, BLOCK_HASH]) unsubscribe() {
+func (hl *headListener[HTH, S, ID, BLOCK_HASH]) unsubscribe() {
if hl.headSubscription != nil {
hl.connected.Store(false)
hl.headSubscription.Unsubscribe()
diff --git a/common/headtracker/head_saver.go b/common/headtracker/head_saver.go
new file mode 100644
index 00000000000..6f461c61225
--- /dev/null
+++ b/common/headtracker/head_saver.go
@@ -0,0 +1,23 @@
+package headtracker
+
+import (
+ "context"
+
+ "github.com/smartcontractkit/chainlink/v2/common/types"
+)
+
+// HeadSaver is an chain agnostic interface for saving and loading heads
+// Different chains will instantiate generic HeadSaver type with their native Head and BlockHash types.
+type HeadSaver[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] interface {
+ // Save updates the latest block number, if indeed the latest, and persists
+ // this number in case of reboot.
+ Save(ctx context.Context, head H) error
+ // Load loads latest heads up to latestFinalized - historyDepth, returns the latest chain.
+ Load(ctx context.Context, latestFinalized int64) (H, error)
+ // LatestChain returns the block header with the highest number that has been seen, or nil.
+ LatestChain() H
+ // Chain returns a head for the specified hash, or nil.
+ Chain(hash BLOCK_HASH) H
+ // MarkFinalized - marks matching block and all it's direct ancestors as finalized
+ MarkFinalized(ctx context.Context, latestFinalized H) error
+}
diff --git a/common/headtracker/head_tracker.go b/common/headtracker/head_tracker.go
index eb9d72f123c..bc7a4910b39 100644
--- a/common/headtracker/head_tracker.go
+++ b/common/headtracker/head_tracker.go
@@ -34,7 +34,17 @@ var (
// HeadsBufferSize - The buffer is used when heads sampling is disabled, to ensure the callback is run for every head
const HeadsBufferSize = 10
-type HeadTracker[
+// HeadTracker holds and stores the block experienced by a particular node in a thread safe manner.
+//
+//go:generate mockery --quiet --name HeadTracker --output ./mocks/ --case=underscore
+type HeadTracker[H types.Head[BLOCK_HASH], BLOCK_HASH types.Hashable] interface {
+ services.Service
+ // Backfill given a head will fill in any missing heads up to latestFinalized
+ Backfill(ctx context.Context, headWithChain, latestFinalized H) (err error)
+ LatestChain() H
+}
+
+type headTracker[
HTH htrktypes.Head[BLOCK_HASH, ID],
S types.Subscription,
ID types.ID,
@@ -42,17 +52,17 @@ type HeadTracker[
] struct {
services.StateMachine
log logger.SugaredLogger
- headBroadcaster types.HeadBroadcaster[HTH, BLOCK_HASH]
- headSaver types.HeadSaver[HTH, BLOCK_HASH]
+ headBroadcaster HeadBroadcaster[HTH, BLOCK_HASH]
+ headSaver HeadSaver[HTH, BLOCK_HASH]
mailMon *mailbox.Monitor
client htrktypes.Client[HTH, S, ID, BLOCK_HASH]
- chainID ID
+ chainID types.ID
config htrktypes.Config
htConfig htrktypes.HeadTrackerConfig
backfillMB *mailbox.Mailbox[HTH]
broadcastMB *mailbox.Mailbox[HTH]
- headListener types.HeadListener[HTH, BLOCK_HASH]
+ headListener HeadListener[HTH, BLOCK_HASH]
chStop services.StopChan
wgDone sync.WaitGroup
getNilHead func() HTH
@@ -69,14 +79,14 @@ func NewHeadTracker[
client htrktypes.Client[HTH, S, ID, BLOCK_HASH],
config htrktypes.Config,
htConfig htrktypes.HeadTrackerConfig,
- headBroadcaster types.HeadBroadcaster[HTH, BLOCK_HASH],
- headSaver types.HeadSaver[HTH, BLOCK_HASH],
+ headBroadcaster HeadBroadcaster[HTH, BLOCK_HASH],
+ headSaver HeadSaver[HTH, BLOCK_HASH],
mailMon *mailbox.Monitor,
getNilHead func() HTH,
-) types.HeadTracker[HTH, BLOCK_HASH] {
+) HeadTracker[HTH, BLOCK_HASH] {
chStop := make(chan struct{})
lggr = logger.Named(lggr, "HeadTracker")
- return &HeadTracker[HTH, S, ID, BLOCK_HASH]{
+ return &headTracker[HTH, S, ID, BLOCK_HASH]{
headBroadcaster: headBroadcaster,
client: client,
chainID: client.ConfiguredChainID(),
@@ -94,7 +104,7 @@ func NewHeadTracker[
}
// Start starts HeadTracker service.
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) Start(ctx context.Context) error {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Start(ctx context.Context) error {
return ht.StartOnce("HeadTracker", func() error {
ht.log.Debugw("Starting HeadTracker", "chainID", ht.chainID)
// NOTE: Always try to start the head tracker off with whatever the
@@ -123,7 +133,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) Start(ctx context.Context) error
})
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) handleInitialHead(ctx context.Context) error {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) handleInitialHead(ctx context.Context) error {
initialHead, err := ht.client.HeadByNumber(ctx, nil)
if err != nil {
return fmt.Errorf("failed to fetch initial head: %w", err)
@@ -167,7 +177,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) handleInitialHead(ctx context.Con
}
// Close stops HeadTracker service.
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) Close() error {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Close() error {
return ht.StopOnce("HeadTracker", func() error {
close(ht.chStop)
ht.wgDone.Wait()
@@ -175,17 +185,17 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) Close() error {
})
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) Name() string {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Name() string {
return ht.log.Name()
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) HealthReport() map[string]error {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) HealthReport() map[string]error {
report := map[string]error{ht.Name(): ht.Healthy()}
services.CopyHealth(report, ht.headListener.HealthReport())
return report
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) Backfill(ctx context.Context, headWithChain, latestFinalized HTH) (err error) {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Backfill(ctx context.Context, headWithChain, latestFinalized HTH) (err error) {
if !latestFinalized.IsValid() {
return errors.New("can not perform backfill without a valid latestFinalized head")
}
@@ -201,11 +211,11 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) Backfill(ctx context.Context, hea
return ht.backfill(ctx, headWithChain, latestFinalized)
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) LatestChain() HTH {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) LatestChain() HTH {
return ht.headSaver.LatestChain()
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) handleNewHead(ctx context.Context, head HTH) error {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) handleNewHead(ctx context.Context, head HTH) error {
prevHead := ht.headSaver.LatestChain()
ht.log.Debugw(fmt.Sprintf("Received new head %v", head.BlockNumber()),
@@ -250,7 +260,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) handleNewHead(ctx context.Context
return nil
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) broadcastLoop() {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) broadcastLoop() {
defer ht.wgDone.Done()
samplingInterval := ht.htConfig.SamplingInterval()
@@ -289,7 +299,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) broadcastLoop() {
}
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) backfillLoop() {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) backfillLoop() {
defer ht.wgDone.Done()
ctx, cancel := ht.chStop.NewCtx()
@@ -327,7 +337,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) backfillLoop() {
// calculateLatestFinalized - returns latest finalized block. It's expected that currentHeadNumber - is the head of
// canonical chain. There is no guaranties that returned block belongs to the canonical chain. Additional verification
// must be performed before usage.
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) calculateLatestFinalized(ctx context.Context, currentHead HTH) (h HTH, err error) {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) calculateLatestFinalized(ctx context.Context, currentHead HTH) (h HTH, err error) {
if ht.config.FinalityTagEnabled() {
return ht.client.LatestFinalizedBlock(ctx)
}
@@ -343,7 +353,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) calculateLatestFinalized(ctx cont
}
// backfill fetches all missing heads up until the latestFinalizedHead
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) backfill(ctx context.Context, head, latestFinalizedHead HTH) (err error) {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) backfill(ctx context.Context, head, latestFinalizedHead HTH) (err error) {
headBlockNumber := head.BlockNumber()
mark := time.Now()
fetched := 0
@@ -402,7 +412,7 @@ func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) backfill(ctx context.Context, hea
return
}
-func (ht *HeadTracker[HTH, S, ID, BLOCK_HASH]) fetchAndSaveHead(ctx context.Context, n int64, hash BLOCK_HASH) (HTH, error) {
+func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) fetchAndSaveHead(ctx context.Context, n int64, hash BLOCK_HASH) (HTH, error) {
ht.log.Debugw("Fetching head", "blockHeight", n, "blockHash", hash)
head, err := ht.client.HeadByHash(ctx, hash)
if err != nil {
diff --git a/common/mocks/head_broadcaster.go b/common/headtracker/mocks/head_broadcaster.go
similarity index 87%
rename from common/mocks/head_broadcaster.go
rename to common/headtracker/mocks/head_broadcaster.go
index 265fceae91e..e30da907df5 100644
--- a/common/mocks/head_broadcaster.go
+++ b/common/headtracker/mocks/head_broadcaster.go
@@ -5,8 +5,10 @@ package mocks
import (
context "context"
- types "github.com/smartcontractkit/chainlink/v2/common/types"
+ headtracker "github.com/smartcontractkit/chainlink/v2/common/headtracker"
mock "github.com/stretchr/testify/mock"
+
+ types "github.com/smartcontractkit/chainlink/v2/common/types"
)
// HeadBroadcaster is an autogenerated mock type for the HeadBroadcaster type
@@ -112,7 +114,7 @@ func (_m *HeadBroadcaster[H, BLOCK_HASH]) Start(_a0 context.Context) error {
}
// Subscribe provides a mock function with given fields: callback
-func (_m *HeadBroadcaster[H, BLOCK_HASH]) Subscribe(callback types.HeadTrackable[H, BLOCK_HASH]) (H, func()) {
+func (_m *HeadBroadcaster[H, BLOCK_HASH]) Subscribe(callback headtracker.HeadTrackable[H, BLOCK_HASH]) (H, func()) {
ret := _m.Called(callback)
if len(ret) == 0 {
@@ -121,16 +123,16 @@ func (_m *HeadBroadcaster[H, BLOCK_HASH]) Subscribe(callback types.HeadTrackable
var r0 H
var r1 func()
- if rf, ok := ret.Get(0).(func(types.HeadTrackable[H, BLOCK_HASH]) (H, func())); ok {
+ if rf, ok := ret.Get(0).(func(headtracker.HeadTrackable[H, BLOCK_HASH]) (H, func())); ok {
return rf(callback)
}
- if rf, ok := ret.Get(0).(func(types.HeadTrackable[H, BLOCK_HASH]) H); ok {
+ if rf, ok := ret.Get(0).(func(headtracker.HeadTrackable[H, BLOCK_HASH]) H); ok {
r0 = rf(callback)
} else {
r0 = ret.Get(0).(H)
}
- if rf, ok := ret.Get(1).(func(types.HeadTrackable[H, BLOCK_HASH]) func()); ok {
+ if rf, ok := ret.Get(1).(func(headtracker.HeadTrackable[H, BLOCK_HASH]) func()); ok {
r1 = rf(callback)
} else {
if ret.Get(1) != nil {
diff --git a/common/types/mocks/head_trackable.go b/common/headtracker/mocks/head_trackable.go
similarity index 99%
rename from common/types/mocks/head_trackable.go
rename to common/headtracker/mocks/head_trackable.go
index 55f0ebd288e..22bc5cb280a 100644
--- a/common/types/mocks/head_trackable.go
+++ b/common/headtracker/mocks/head_trackable.go
@@ -5,8 +5,9 @@ package mocks
import (
context "context"
- types "github.com/smartcontractkit/chainlink/v2/common/types"
mock "github.com/stretchr/testify/mock"
+
+ types "github.com/smartcontractkit/chainlink/v2/common/types"
)
// HeadTrackable is an autogenerated mock type for the HeadTrackable type
diff --git a/common/mocks/head_tracker.go b/common/headtracker/mocks/head_tracker.go
similarity index 99%
rename from common/mocks/head_tracker.go
rename to common/headtracker/mocks/head_tracker.go
index fea31a1d6eb..9261ef3221b 100644
--- a/common/mocks/head_tracker.go
+++ b/common/headtracker/mocks/head_tracker.go
@@ -5,8 +5,9 @@ package mocks
import (
context "context"
- types "github.com/smartcontractkit/chainlink/v2/common/types"
mock "github.com/stretchr/testify/mock"
+
+ types "github.com/smartcontractkit/chainlink/v2/common/types"
)
// HeadTracker is an autogenerated mock type for the HeadTracker type
diff --git a/common/headtracker/types/head.go b/common/headtracker/types/head.go
index c2d7e262ac7..d1f99031bf6 100644
--- a/common/headtracker/types/head.go
+++ b/common/headtracker/types/head.go
@@ -4,7 +4,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/common/types"
)
-//go:generate mockery --quiet --name Head --output ./mocks/ --case=underscore
type Head[BLOCK_HASH types.Hashable, CHAIN_ID types.ID] interface {
types.Head[BLOCK_HASH]
// ChainID returns the chain ID that the head is for
diff --git a/common/headtracker/types/mocks/head.go b/common/headtracker/types/mocks/head.go
deleted file mode 100644
index f86df1d7fce..00000000000
--- a/common/headtracker/types/mocks/head.go
+++ /dev/null
@@ -1,254 +0,0 @@
-// Code generated by mockery v2.38.0. DO NOT EDIT.
-
-package mocks
-
-import (
- big "math/big"
-
- mock "github.com/stretchr/testify/mock"
-
- time "time"
-
- types "github.com/smartcontractkit/chainlink/v2/common/types"
-)
-
-// Head is an autogenerated mock type for the Head type
-type Head[BLOCK_HASH types.Hashable, CHAIN_ID types.ID] struct {
- mock.Mock
-}
-
-// BlockDifficulty provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) BlockDifficulty() *big.Int {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for BlockDifficulty")
- }
-
- var r0 *big.Int
- if rf, ok := ret.Get(0).(func() *big.Int); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(*big.Int)
- }
- }
-
- return r0
-}
-
-// BlockHash provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) BlockHash() BLOCK_HASH {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for BlockHash")
- }
-
- var r0 BLOCK_HASH
- if rf, ok := ret.Get(0).(func() BLOCK_HASH); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(BLOCK_HASH)
- }
-
- return r0
-}
-
-// BlockNumber provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) BlockNumber() int64 {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for BlockNumber")
- }
-
- var r0 int64
- if rf, ok := ret.Get(0).(func() int64); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(int64)
- }
-
- return r0
-}
-
-// ChainID provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) ChainID() CHAIN_ID {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for ChainID")
- }
-
- var r0 CHAIN_ID
- if rf, ok := ret.Get(0).(func() CHAIN_ID); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(CHAIN_ID)
- }
-
- return r0
-}
-
-// ChainLength provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) ChainLength() uint32 {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for ChainLength")
- }
-
- var r0 uint32
- if rf, ok := ret.Get(0).(func() uint32); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(uint32)
- }
-
- return r0
-}
-
-// EarliestHeadInChain provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) EarliestHeadInChain() types.Head[BLOCK_HASH] {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for EarliestHeadInChain")
- }
-
- var r0 types.Head[BLOCK_HASH]
- if rf, ok := ret.Get(0).(func() types.Head[BLOCK_HASH]); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(types.Head[BLOCK_HASH])
- }
- }
-
- return r0
-}
-
-// GetParent provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) GetParent() types.Head[BLOCK_HASH] {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for GetParent")
- }
-
- var r0 types.Head[BLOCK_HASH]
- if rf, ok := ret.Get(0).(func() types.Head[BLOCK_HASH]); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(types.Head[BLOCK_HASH])
- }
- }
-
- return r0
-}
-
-// GetParentHash provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) GetParentHash() BLOCK_HASH {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for GetParentHash")
- }
-
- var r0 BLOCK_HASH
- if rf, ok := ret.Get(0).(func() BLOCK_HASH); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(BLOCK_HASH)
- }
-
- return r0
-}
-
-// GetTimestamp provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) GetTimestamp() time.Time {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for GetTimestamp")
- }
-
- var r0 time.Time
- if rf, ok := ret.Get(0).(func() time.Time); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(time.Time)
- }
-
- return r0
-}
-
-// HasChainID provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) HasChainID() bool {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for HasChainID")
- }
-
- var r0 bool
- if rf, ok := ret.Get(0).(func() bool); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(bool)
- }
-
- return r0
-}
-
-// HashAtHeight provides a mock function with given fields: blockNum
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) HashAtHeight(blockNum int64) BLOCK_HASH {
- ret := _m.Called(blockNum)
-
- if len(ret) == 0 {
- panic("no return value specified for HashAtHeight")
- }
-
- var r0 BLOCK_HASH
- if rf, ok := ret.Get(0).(func(int64) BLOCK_HASH); ok {
- r0 = rf(blockNum)
- } else {
- r0 = ret.Get(0).(BLOCK_HASH)
- }
-
- return r0
-}
-
-// IsValid provides a mock function with given fields:
-func (_m *Head[BLOCK_HASH, CHAIN_ID]) IsValid() bool {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for IsValid")
- }
-
- var r0 bool
- if rf, ok := ret.Get(0).(func() bool); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(bool)
- }
-
- return r0
-}
-
-// NewHead creates a new instance of Head. 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 NewHead[BLOCK_HASH types.Hashable, CHAIN_ID types.ID](t interface {
- mock.TestingT
- Cleanup(func())
-}) *Head[BLOCK_HASH, CHAIN_ID] {
- mock := &Head[BLOCK_HASH, CHAIN_ID]{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/common/headtracker/types/mocks/subscription.go b/common/headtracker/types/mocks/subscription.go
deleted file mode 100644
index b9cb7886d1d..00000000000
--- a/common/headtracker/types/mocks/subscription.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Code generated by mockery v2.28.1. DO NOT EDIT.
-
-package mocks
-
-import mock "github.com/stretchr/testify/mock"
-
-// Subscription is an autogenerated mock type for the Subscription type
-type Subscription struct {
- mock.Mock
-}
-
-// Err provides a mock function with given fields:
-func (_m *Subscription) Err() <-chan error {
- ret := _m.Called()
-
- var r0 <-chan error
- if rf, ok := ret.Get(0).(func() <-chan error); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(<-chan error)
- }
- }
-
- return r0
-}
-
-// Unsubscribe provides a mock function with given fields:
-func (_m *Subscription) Unsubscribe() {
- _m.Called()
-}
-
-type mockConstructorTestingTNewSubscription interface {
- mock.TestingT
- Cleanup(func())
-}
-
-// NewSubscription creates a new instance of Subscription. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-func NewSubscription(t mockConstructorTestingTNewSubscription) *Subscription {
- mock := &Subscription{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go
index a13673bf91b..1651f6417bf 100644
--- a/common/txmgr/broadcaster.go
+++ b/common/txmgr/broadcaster.go
@@ -689,7 +689,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) save
// is relatively benign and probably nobody will ever run into it in
// practice, but something to be aware of.
if etx.PipelineTaskRunID.Valid && eb.resumeCallback != nil && etx.SignalCallback {
- err := eb.resumeCallback(etx.PipelineTaskRunID.UUID, nil, fmt.Errorf("fatal error while sending transaction: %s", etx.Error.String))
+ err := eb.resumeCallback(ctx, etx.PipelineTaskRunID.UUID, nil, fmt.Errorf("fatal error while sending transaction: %s", etx.Error.String))
if errors.Is(err, sql.ErrNoRows) {
lgr.Debugw("callback missing or already resumed", "etxID", etx.ID)
} else if err != nil {
diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go
index 53e1c3c4206..d61f9a3dddd 100644
--- a/common/txmgr/confirmer.go
+++ b/common/txmgr/confirmer.go
@@ -1120,7 +1120,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Res
}
ec.lggr.Debugw("Callback: resuming tx with receipt", "output", output, "taskErr", taskErr, "pipelineTaskRunID", data.ID)
- if err := ec.resumeCallback(data.ID, output, taskErr); err != nil {
+ if err := ec.resumeCallback(ctx, data.ID, output, taskErr); err != nil {
return fmt.Errorf("failed to resume suspended pipeline run: %w", err)
}
// Mark tx as having completed callback
diff --git a/common/txmgr/mocks/tx_manager.go b/common/txmgr/mocks/tx_manager.go
index 37b0822941d..a5f05219217 100644
--- a/common/txmgr/mocks/tx_manager.go
+++ b/common/txmgr/mocks/tx_manager.go
@@ -184,7 +184,7 @@ func (_m *TxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) FindTx
}
// FindTxesWithAttemptsAndReceiptsByIdsAndState provides a mock function with given fields: ctx, ids, states, chainID
-func (_m *TxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []big.Int, states []txmgrtypes.TxState, chainID *big.Int) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
+func (_m *TxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []int64, states []txmgrtypes.TxState, chainID *big.Int) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
ret := _m.Called(ctx, ids, states, chainID)
if len(ret) == 0 {
@@ -193,10 +193,10 @@ func (_m *TxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) FindTx
var r0 []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, []big.Int, []txmgrtypes.TxState, *big.Int) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, []int64, []txmgrtypes.TxState, *big.Int) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
return rf(ctx, ids, states, chainID)
}
- if rf, ok := ret.Get(0).(func(context.Context, []big.Int, []txmgrtypes.TxState, *big.Int) []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, []int64, []txmgrtypes.TxState, *big.Int) []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
r0 = rf(ctx, ids, states, chainID)
} else {
if ret.Get(0) != nil {
@@ -204,7 +204,7 @@ func (_m *TxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) FindTx
}
}
- if rf, ok := ret.Get(1).(func(context.Context, []big.Int, []txmgrtypes.TxState, *big.Int) error); ok {
+ if rf, ok := ret.Get(1).(func(context.Context, []int64, []txmgrtypes.TxState, *big.Int) error); ok {
r1 = rf(ctx, ids, states, chainID)
} else {
r1 = ret.Error(1)
diff --git a/common/txmgr/resender.go b/common/txmgr/resender.go
index 8c2dd6b827e..b752ec63f13 100644
--- a/common/txmgr/resender.go
+++ b/common/txmgr/resender.go
@@ -140,9 +140,6 @@ func (er *Resender[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) resendUnco
return fmt.Errorf("Resender failed getting enabled keys for chain %s: %w", er.chainID.String(), err)
}
- // Tracker currently disabled for BCI-2638; refactor required
- // resendAddresses = append(resendAddresses, er.tracker.GetAbandonedAddresses()...)
-
ageThreshold := er.txConfig.ResendAfterThreshold()
maxInFlightTransactions := er.txConfig.MaxInFlight()
olderThan := time.Now().Add(-ageThreshold)
diff --git a/common/txmgr/strategies.go b/common/txmgr/strategies.go
index 3772e6d1d20..6e037658854 100644
--- a/common/txmgr/strategies.go
+++ b/common/txmgr/strategies.go
@@ -3,7 +3,6 @@ package txmgr
import (
"context"
"fmt"
- "time"
"github.com/google/uuid"
@@ -14,9 +13,9 @@ var _ txmgrtypes.TxStrategy = SendEveryStrategy{}
// NewQueueingTxStrategy creates a new TxStrategy that drops the oldest transactions after the
// queue size is exceeded if a queue size is specified, and otherwise does not drop transactions.
-func NewQueueingTxStrategy(subject uuid.UUID, queueSize uint32, queryTimeout time.Duration) (strategy txmgrtypes.TxStrategy) {
+func NewQueueingTxStrategy(subject uuid.UUID, queueSize uint32) (strategy txmgrtypes.TxStrategy) {
if queueSize > 0 {
- strategy = NewDropOldestStrategy(subject, queueSize, queryTimeout)
+ strategy = NewDropOldestStrategy(subject, queueSize)
} else {
strategy = SendEveryStrategy{}
}
@@ -41,15 +40,14 @@ var _ txmgrtypes.TxStrategy = DropOldestStrategy{}
// DropOldestStrategy will send the newest N transactions, older ones will be
// removed from the queue
type DropOldestStrategy struct {
- subject uuid.UUID
- queueSize uint32
- queryTimeout time.Duration
+ subject uuid.UUID
+ queueSize uint32
}
// NewDropOldestStrategy creates a new TxStrategy that drops the oldest transactions after the
// queue size is exceeded.
-func NewDropOldestStrategy(subject uuid.UUID, queueSize uint32, queryTimeout time.Duration) DropOldestStrategy {
- return DropOldestStrategy{subject, queueSize, queryTimeout}
+func NewDropOldestStrategy(subject uuid.UUID, queueSize uint32) DropOldestStrategy {
+ return DropOldestStrategy{subject, queueSize}
}
func (s DropOldestStrategy) Subject() uuid.NullUUID {
@@ -57,10 +55,6 @@ func (s DropOldestStrategy) Subject() uuid.NullUUID {
}
func (s DropOldestStrategy) PruneQueue(ctx context.Context, pruneService txmgrtypes.UnstartedTxQueuePruner) (ids []int64, err error) {
- var cancel context.CancelFunc
- ctx, cancel = context.WithTimeout(ctx, s.queryTimeout)
- defer cancel()
-
// NOTE: We prune one less than the queue size to prevent the queue from exceeding the max queue size. Which could occur if a new transaction is added to the queue right after we prune.
ids, err = pruneService.PruneUnstartedTxQueue(ctx, s.queueSize-1, s.subject)
if err != nil {
diff --git a/common/txmgr/tracker.go b/common/txmgr/tracker.go
index c63d9c264fc..a7236472710 100644
--- a/common/txmgr/tracker.go
+++ b/common/txmgr/tracker.go
@@ -8,6 +8,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
@@ -22,17 +23,10 @@ const (
// handleTxesTimeout represents a sanity limit on how long handleTxesByState
// should take to complete
handleTxesTimeout = 10 * time.Minute
+ // batchSize is the number of txes to fetch from the txStore at once
+ batchSize = 1000
)
-// AbandonedTx is a transaction who's 'FromAddress' was removed from the KeyStore(by the Node Operator).
-// Thus, any new attempts for this Tx can't be signed/created. This means no fee bumping can be done.
-// However, the Tx may still have live attempts in the chain's mempool, and could get confirmed on the
-// chain as-is. Thus, the TXM should not directly discard this Tx.
-type AbandonedTx[ADDR types.Hashable] struct {
- id int64
- fromAddress ADDR
-}
-
// Tracker tracks all transactions which have abandoned fromAddresses.
// The fromAddresses can be deleted by Node Operators from the KeyStore. In such cases,
// existing in-flight transactions for these fromAddresses are considered abandoned too.
@@ -48,19 +42,22 @@ type Tracker[
FEE feetypes.Fee,
] struct {
services.StateMachine
- txStore txmgrtypes.TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]
- keyStore txmgrtypes.KeyStore[ADDR, CHAIN_ID, SEQ]
- chainID CHAIN_ID
- lggr logger.Logger
- enabledAddrs map[ADDR]bool
- txCache map[int64]AbandonedTx[ADDR]
- ttl time.Duration
+ txStore txmgrtypes.TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]
+ keyStore txmgrtypes.KeyStore[ADDR, CHAIN_ID, SEQ]
+ chainID CHAIN_ID
+ lggr logger.Logger
+
lock sync.Mutex
- mb *mailbox.Mailbox[int64]
- wg sync.WaitGroup
- isStarted bool
- ctx context.Context
- ctxCancel context.CancelFunc
+ enabledAddrs map[ADDR]bool
+ txCache map[int64]ADDR // cache tx fromAddress by txID
+
+ ttl time.Duration
+ mb *mailbox.Mailbox[int64]
+
+ initSync sync.Mutex
+ wg sync.WaitGroup
+ chStop services.StopChan
+ isStarted bool
}
func NewTracker[
@@ -83,7 +80,7 @@ func NewTracker[
chainID: chainID,
lggr: logger.Named(lggr, "TxMgrTracker"),
enabledAddrs: map[ADDR]bool{},
- txCache: map[int64]AbandonedTx[ADDR]{},
+ txCache: map[int64]ADDR{},
ttl: defaultTTL,
mb: mailbox.NewSingle[int64](),
lock: sync.Mutex{},
@@ -99,75 +96,84 @@ func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Start(ctx c
}
func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) startInternal(ctx context.Context) (err error) {
- tr.lock.Lock()
- defer tr.lock.Unlock()
-
- tr.ctx, tr.ctxCancel = context.WithCancel(context.Background())
+ tr.initSync.Lock()
+ defer tr.initSync.Unlock()
if err := tr.setEnabledAddresses(ctx); err != nil {
return fmt.Errorf("failed to set enabled addresses: %w", err)
}
- tr.lggr.Info("Enabled addresses set")
+ tr.lggr.Infof("enabled addresses set for chainID %v", tr.chainID)
- if err := tr.trackAbandonedTxes(ctx); err != nil {
- return fmt.Errorf("failed to track abandoned txes: %w", err)
- }
-
- tr.isStarted = true
- if len(tr.txCache) == 0 {
- tr.lggr.Info("no abandoned txes found, skipping runLoop")
- return nil
- }
-
- tr.lggr.Infof("%d abandoned txes found, starting runLoop", len(tr.txCache))
+ tr.chStop = make(chan struct{})
tr.wg.Add(1)
- go tr.runLoop()
+ go tr.runLoop(tr.chStop.NewCtx())
+ tr.isStarted = true
return nil
}
func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Close() error {
- tr.lock.Lock()
- defer tr.lock.Unlock()
return tr.StopOnce("Tracker", func() error {
return tr.closeInternal()
})
}
func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) closeInternal() error {
+ tr.initSync.Lock()
+ defer tr.initSync.Unlock()
+
tr.lggr.Info("stopping tracker")
if !tr.isStarted {
- return fmt.Errorf("tracker not started")
+ return fmt.Errorf("tracker is not started: %w", services.ErrAlreadyStopped)
}
- tr.ctxCancel()
+
+ close(tr.chStop)
tr.wg.Wait()
tr.isStarted = false
return nil
}
-func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop() {
+func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop(ctx context.Context, cancel context.CancelFunc) {
defer tr.wg.Done()
+ defer cancel()
+
+ if err := tr.trackAbandonedTxes(ctx); err != nil {
+ tr.lggr.Errorf("failed to track abandoned txes: %v", err)
+ return
+ }
+ if err := tr.handleTxesByState(ctx); err != nil {
+ tr.lggr.Errorf("failed to handle txes by state: %v", err)
+ return
+ }
+ if tr.AbandonedTxCount() == 0 {
+ tr.lggr.Info("no abandoned txes found, skipping runLoop")
+ return
+ }
+ tr.lggr.Infof("%d abandoned txes found, starting runLoop", tr.AbandonedTxCount())
+
ttlExceeded := time.NewTicker(tr.ttl)
defer ttlExceeded.Stop()
for {
select {
case <-tr.mb.Notify():
for {
- if tr.ctx.Err() != nil {
- return
- }
- blockHeight, exists := tr.mb.Retrieve()
- if !exists {
+ blockHeight := tr.mb.RetrieveLatestAndClear()
+ if blockHeight == 0 {
break
}
- if err := tr.HandleTxesByState(tr.ctx, blockHeight); err != nil {
- tr.lggr.Errorw(fmt.Errorf("failed to handle txes by state: %w", err).Error())
+ if err := tr.handleTxesByState(ctx); err != nil {
+ tr.lggr.Errorf("failed to handle txes by state: %v", err)
+ return
+ }
+ if tr.AbandonedTxCount() == 0 {
+ tr.lggr.Info("all abandoned txes handled, stopping runLoop")
+ return
}
}
case <-ttlExceeded.C:
tr.lggr.Info("ttl exceeded")
- tr.MarkAllTxesFatal(tr.ctx)
+ tr.markAllTxesFatal(ctx)
return
- case <-tr.ctx.Done():
+ case <-ctx.Done():
return
}
}
@@ -177,24 +183,31 @@ func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) GetAbandone
tr.lock.Lock()
defer tr.lock.Unlock()
- if !tr.isStarted {
- return []ADDR{}
- }
-
abandonedAddrs := make([]ADDR, len(tr.txCache))
- for _, atx := range tr.txCache {
- abandonedAddrs = append(abandonedAddrs, atx.fromAddress)
+ for _, fromAddress := range tr.txCache {
+ abandonedAddrs = append(abandonedAddrs, fromAddress)
}
return abandonedAddrs
}
-func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) IsStarted() bool {
+// AbandonedTxCount returns the number of abandoned txes currently being tracked
+func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) AbandonedTxCount() int {
tr.lock.Lock()
defer tr.lock.Unlock()
+ return len(tr.txCache)
+}
+
+func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) IsStarted() bool {
+ tr.initSync.Lock()
+ defer tr.initSync.Unlock()
return tr.isStarted
}
+// setEnabledAddresses is called on startup to set the enabled addresses for the chain
func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) setEnabledAddresses(ctx context.Context) error {
+ tr.lock.Lock()
+ defer tr.lock.Unlock()
+
enabledAddrs, err := tr.keyStore.EnabledAddressesForChain(ctx, tr.chainID)
if err != nil {
return fmt.Errorf("failed to get enabled addresses for chain: %w", err)
@@ -210,54 +223,58 @@ func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) setEnabledA
return nil
}
-// trackAbandonedTxes called once to find and insert all abandoned txes into the tracker.
+// trackAbandonedTxes called on startup to find and insert all abandoned txes into the tracker.
func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) trackAbandonedTxes(ctx context.Context) (err error) {
- if tr.isStarted {
- return fmt.Errorf("tracker already started")
- }
-
- tr.lggr.Info("Retrieving non fatal transactions from txStore")
- nonFatalTxes, err := tr.txStore.GetNonFatalTransactions(ctx, tr.chainID)
- if err != nil {
- return fmt.Errorf("failed to get non fatal txes from txStore: %w", err)
- }
-
- // insert abandoned txes
- for _, tx := range nonFatalTxes {
- if !tr.enabledAddrs[tx.FromAddress] {
- tr.insertTx(tx)
+ return sqlutil.Batch(func(offset, limit uint) (count uint, err error) {
+ var enabledAddrs []ADDR
+ for addr := range tr.enabledAddrs {
+ enabledAddrs = append(enabledAddrs, addr)
}
- }
- if err := tr.handleTxesByState(ctx, 0); err != nil {
- return fmt.Errorf("failed to handle txes by state: %w", err)
- }
-
- return nil
+ nonFatalTxes, err := tr.txStore.GetAbandonedTransactionsByBatch(ctx, tr.chainID, enabledAddrs, offset, limit)
+ if err != nil {
+ return 0, fmt.Errorf("failed to get non fatal txes from txStore: %w", err)
+ }
+ // insert abandoned txes
+ tr.lock.Lock()
+ for _, tx := range nonFatalTxes {
+ if !tr.enabledAddrs[tx.FromAddress] {
+ tr.txCache[tx.ID] = tx.FromAddress
+ tr.lggr.Debugf("inserted tx %v", tx.ID)
+ }
+ }
+ tr.lock.Unlock()
+ return uint(len(nonFatalTxes)), nil
+ }, batchSize)
}
-func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) HandleTxesByState(ctx context.Context, blockHeight int64) error {
+// handleTxesByState handles all txes in the txCache by their state
+// It's called on every new blockHeight and also on startup to handle all txes in the txCache
+func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) handleTxesByState(ctx context.Context) error {
tr.lock.Lock()
defer tr.lock.Unlock()
- tr.ctx, tr.ctxCancel = context.WithTimeout(ctx, handleTxesTimeout)
- defer tr.ctxCancel()
- return tr.handleTxesByState(ctx, blockHeight)
-}
+ ctx, cancel := context.WithTimeout(ctx, handleTxesTimeout)
+ defer cancel()
-func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) handleTxesByState(ctx context.Context, blockHeight int64) error {
- tr.lggr.Info("Handling transactions by state")
+ for id := range tr.txCache {
+ if ctx.Err() != nil {
+ return ctx.Err()
+ }
- for id, atx := range tr.txCache {
- tx, err := tr.txStore.GetTxByID(ctx, atx.id)
+ tx, err := tr.txStore.GetTxByID(ctx, id)
if err != nil {
- return fmt.Errorf("failed to get tx by ID: %w", err)
+ tr.lggr.Errorf("failed to get tx by ID: %v", err)
+ continue
+ }
+ if tx == nil {
+ tr.lggr.Warnf("tx with ID %v no longer exists, removing from tracker", id)
+ delete(tr.txCache, id)
+ continue
}
switch tx.State {
case TxConfirmed:
- if err := tr.handleConfirmedTx(tx, blockHeight); err != nil {
- return fmt.Errorf("failed to handle confirmed txes: %w", err)
- }
+ // TODO: Handle finalized state https://smartcontract-it.atlassian.net/browse/BCI-2920
case TxConfirmedMissingReceipt, TxUnconfirmed:
// Keep tracking tx
case TxInProgress, TxUnstarted:
@@ -266,50 +283,20 @@ func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) handleTxesB
// is deleted, we can't sign it.
errMsg := "The FromAddress for this Tx was deleted before this Tx could be broadcast to the chain."
if err := tr.markTxFatal(ctx, tx, errMsg); err != nil {
- return fmt.Errorf("failed to mark tx as fatal: %w", err)
+ tr.lggr.Errorf("failed to mark tx as fatal: %v", err)
+ continue
}
delete(tr.txCache, id)
case TxFatalError:
delete(tr.txCache, id)
default:
- tr.lggr.Errorw(fmt.Sprintf("unhandled transaction state: %v", tx.State))
+ tr.lggr.Errorf("unhandled transaction state: %v", tx.State)
}
}
return nil
}
-// handleConfirmedTx removes a transaction from the tracker if it's been finalized on chain
-func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) handleConfirmedTx(
- tx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE],
- blockHeight int64,
-) error {
- finalized, err := tr.txStore.IsTxFinalized(tr.ctx, blockHeight, tx.ID, tr.chainID)
- if err != nil {
- return fmt.Errorf("failed to check if tx is finalized: %w", err)
- }
-
- if finalized {
- delete(tr.txCache, tx.ID)
- }
-
- return nil
-}
-
-// insertTx inserts a transaction into the tracker as an AbandonedTx
-func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) insertTx(
- tx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) {
- if _, contains := tr.txCache[tx.ID]; contains {
- return
- }
-
- tr.txCache[tx.ID] = AbandonedTx[ADDR]{
- id: tx.ID,
- fromAddress: tx.FromAddress,
- }
- tr.lggr.Debugw(fmt.Sprintf("inserted tx %v", tx.ID))
-}
-
func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) markTxFatal(ctx context.Context,
tx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE],
errMsg string) error {
@@ -323,22 +310,26 @@ func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) markTxFatal
return nil
}
-func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) MarkAllTxesFatal(ctx context.Context) {
+// markAllTxesFatal tries to mark all txes in the txCache as fatal and removes them from the cache
+func (tr *Tracker[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) markAllTxesFatal(ctx context.Context) {
tr.lock.Lock()
defer tr.lock.Unlock()
+
errMsg := fmt.Sprintf(
- "fromAddress for this Tx was deleted, and existing attempts onchain didn't finalize within %d hours, thus this Tx was abandoned.",
+ "tx abandoned: fromAddress for this tx was deleted and existing attempts didn't finalize onchain within %d hours",
int(tr.ttl.Hours()))
- for _, atx := range tr.txCache {
- tx, err := tr.txStore.GetTxByID(ctx, atx.id)
+ for id := range tr.txCache {
+ tx, err := tr.txStore.GetTxByID(ctx, id)
if err != nil {
- tr.lggr.Errorw(fmt.Errorf("failed to get tx by ID: %w", err).Error())
+ tr.lggr.Errorf("failed to get tx by ID: %v", err)
+ delete(tr.txCache, id)
continue
}
if err := tr.markTxFatal(ctx, tx, errMsg); err != nil {
- tr.lggr.Errorw(fmt.Errorf("failed to mark tx as abandoned: %w", err).Error())
+ tr.lggr.Errorf("failed to mark tx as abandoned: %v", err)
}
+ delete(tr.txCache, id)
}
}
diff --git a/common/txmgr/txmgr.go b/common/txmgr/txmgr.go
index fcfd023ece3..4d4eabe5c40 100644
--- a/common/txmgr/txmgr.go
+++ b/common/txmgr/txmgr.go
@@ -17,6 +17,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/utils"
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
+ "github.com/smartcontractkit/chainlink/v2/common/headtracker"
iutils "github.com/smartcontractkit/chainlink/v2/common/internal/utils"
txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types"
"github.com/smartcontractkit/chainlink/v2/common/types"
@@ -26,7 +27,7 @@ import (
// https://www.notion.so/chainlink/Txm-Architecture-Overview-9dc62450cd7a443ba9e7dceffa1a8d6b
// ResumeCallback is assumed to be idempotent
-type ResumeCallback func(id uuid.UUID, result interface{}, err error) error
+type ResumeCallback func(ctx context.Context, id uuid.UUID, result interface{}, err error) error
// TxManager is the main component of the transaction manager.
// It is also the interface to external callers.
@@ -41,7 +42,7 @@ type TxManager[
SEQ types.Sequence,
FEE feetypes.Fee,
] interface {
- types.HeadTrackable[HEAD, BLOCK_HASH]
+ headtracker.HeadTrackable[HEAD, BLOCK_HASH]
services.Service
Trigger(addr ADDR)
CreateTransaction(ctx context.Context, txRequest txmgrtypes.TxRequest[ADDR, TX_HASH]) (etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
@@ -56,7 +57,7 @@ type TxManager[
// Find transactions with a non-null TxMeta field that was provided and a receipt block number greater than or equal to the one provided
FindTxesWithMetaFieldByReceiptBlockNum(ctx context.Context, metaField string, blockNum int64, chainID *big.Int) (txes []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
// Find transactions loaded with transaction attempts and receipts by transaction IDs and states
- FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []big.Int, states []txmgrtypes.TxState, chainID *big.Int) (txes []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
+ FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []int64, states []txmgrtypes.TxState, chainID *big.Int) (txes []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
FindEarliestUnconfirmedBroadcastTime(ctx context.Context) (nullv4.Time, error)
FindEarliestUnconfirmedTxAttemptBlock(ctx context.Context) (nullv4.Int, error)
CountTransactionsByState(ctx context.Context, state txmgrtypes.TxState) (count uint32, err error)
@@ -189,12 +190,9 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Start(ctx
return fmt.Errorf("Txm: Estimator failed to start: %w", err)
}
- /* Tracker currently disabled for BCI-2638; refactor required
- b.logger.Info("Txm starting tracker")
if err := ms.Start(ctx, b.tracker); err != nil {
return fmt.Errorf("Txm: Tracker failed to start: %w", err)
}
- */
b.logger.Info("Txm starting runLoop")
b.wg.Add(1)
@@ -274,12 +272,6 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Close() (m
merr = errors.Join(merr, fmt.Errorf("Txm: failed to close TxAttemptBuilder: %w", err))
}
- /* Tracker currently disabled for BCI-2638; refactor required
- if err := b.tracker.Close(); err != nil {
- merr = errors.Join(merr, fmt.Errorf("Txm: failed to close Tracker: %w", err))
- }
- */
-
return nil
})
}
@@ -328,6 +320,9 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop()
if err := b.broadcaster.closeInternal(); err != nil {
b.logger.Panicw(fmt.Sprintf("Failed to Close Broadcaster: %v", err), "err", err)
}
+ if err := b.tracker.closeInternal(); err != nil {
+ b.logger.Panicw(fmt.Sprintf("Failed to Close Tracker: %v", err), "err", err)
+ }
if err := b.confirmer.closeInternal(); err != nil {
b.logger.Panicw(fmt.Sprintf("Failed to Close Confirmer: %v", err), "err", err)
}
@@ -336,16 +331,17 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop()
close(r.done)
}
var wg sync.WaitGroup
- // two goroutines to handle independent backoff retries starting:
+ // three goroutines to handle independent backoff retries starting:
// - Broadcaster
// - Confirmer
+ // - Tracker
// If chStop is closed, we mark stopped=true so that the main runloop
// can check and exit early if necessary
//
// execReset will not return until either:
- // 1. Both Broadcaster and Confirmer started successfully
+ // 1. Broadcaster, Confirmer, and Tracker all started successfully
// 2. chStop was closed (txmgr exit)
- wg.Add(2)
+ wg.Add(3)
go func() {
defer wg.Done()
// Retry indefinitely on failure
@@ -365,6 +361,25 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop()
}
}
}()
+ go func() {
+ defer wg.Done()
+ // Retry indefinitely on failure
+ backoff := iutils.NewRedialBackoff()
+ for {
+ select {
+ case <-time.After(backoff.Duration()):
+ if err := b.tracker.startInternal(ctx); err != nil {
+ b.logger.Criticalw("Failed to start Tracker", "err", err)
+ b.SvcErrBuffer.Append(err)
+ continue
+ }
+ return
+ case <-b.chStop:
+ stopOnce.Do(func() { stopped = true })
+ return
+ }
+ }
+ }()
go func() {
defer wg.Done()
// Retry indefinitely on failure
@@ -394,8 +409,7 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop()
b.broadcaster.Trigger(address)
case head := <-b.chHeads:
b.confirmer.mb.Deliver(head)
- // Tracker currently disabled for BCI-2638; refactor required
- // b.tracker.mb.Deliver(head.BlockNumber())
+ b.tracker.mb.Deliver(head.BlockNumber())
case reset := <-b.reset:
// This check prevents the weird edge-case where you can select
// into this block after chStop has already been closed and the
@@ -423,12 +437,10 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) runLoop()
if err != nil && (!errors.Is(err, services.ErrAlreadyStopped) || !errors.Is(err, services.ErrCannotStopUnstarted)) {
b.logger.Errorw(fmt.Sprintf("Failed to Close Confirmer: %v", err), "err", err)
}
- /* Tracker currently disabled for BCI-2638; refactor required
err = b.tracker.Close()
if err != nil && (!errors.Is(err, services.ErrAlreadyStopped) || !errors.Is(err, services.ErrCannotStopUnstarted)) {
b.logger.Errorw(fmt.Sprintf("Failed to Close Tracker: %v", err), "err", err)
}
- */
return
case <-keysChanged:
// This check prevents the weird edge-case where you can select
@@ -586,7 +598,7 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxesWi
return
}
-func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []big.Int, states []txmgrtypes.TxState, chainID *big.Int) (txes []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) {
+func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []int64, states []txmgrtypes.TxState, chainID *big.Int) (txes []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) {
txes, err = b.txStore.FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx, ids, states, chainID)
return
}
@@ -666,7 +678,7 @@ func (n *NullTxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) Fin
func (n *NullTxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) FindTxesWithMetaFieldByReceiptBlockNum(ctx context.Context, metaField string, blockNum int64, chainID *big.Int) (txes []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) {
return txes, errors.New(n.ErrMsg)
}
-func (n *NullTxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []big.Int, states []txmgrtypes.TxState, chainID *big.Int) (txes []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) {
+func (n *NullTxManager[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []int64, states []txmgrtypes.TxState, chainID *big.Int) (txes []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) {
return txes, errors.New(n.ErrMsg)
}
diff --git a/common/txmgr/types/mocks/tx_store.go b/common/txmgr/types/mocks/tx_store.go
index 814207d3986..64193afff5b 100644
--- a/common/txmgr/types/mocks/tx_store.go
+++ b/common/txmgr/types/mocks/tx_store.go
@@ -551,7 +551,7 @@ func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxesPen
}
// FindTxesWithAttemptsAndReceiptsByIdsAndState provides a mock function with given fields: ctx, ids, states, chainID
-func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []big.Int, states []txmgrtypes.TxState, chainID *big.Int) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
+func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []int64, states []txmgrtypes.TxState, chainID *big.Int) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
ret := _m.Called(ctx, ids, states, chainID)
if len(ret) == 0 {
@@ -560,10 +560,10 @@ func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxesWit
var r0 []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, []big.Int, []txmgrtypes.TxState, *big.Int) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, []int64, []txmgrtypes.TxState, *big.Int) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
return rf(ctx, ids, states, chainID)
}
- if rf, ok := ret.Get(0).(func(context.Context, []big.Int, []txmgrtypes.TxState, *big.Int) []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, []int64, []txmgrtypes.TxState, *big.Int) []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
r0 = rf(ctx, ids, states, chainID)
} else {
if ret.Get(0) != nil {
@@ -571,7 +571,7 @@ func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxesWit
}
}
- if rf, ok := ret.Get(1).(func(context.Context, []big.Int, []txmgrtypes.TxState, *big.Int) error); ok {
+ if rf, ok := ret.Get(1).(func(context.Context, []int64, []txmgrtypes.TxState, *big.Int) error); ok {
r1 = rf(ctx, ids, states, chainID)
} else {
r1 = ret.Error(1)
@@ -700,29 +700,29 @@ func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxsRequ
return r0, r1
}
-// GetInProgressTxAttempts provides a mock function with given fields: ctx, address, chainID
-func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) GetInProgressTxAttempts(ctx context.Context, address ADDR, chainID CHAIN_ID) ([]txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
- ret := _m.Called(ctx, address, chainID)
+// GetAbandonedTransactionsByBatch provides a mock function with given fields: ctx, chainID, enabledAddrs, offset, limit
+func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) GetAbandonedTransactionsByBatch(ctx context.Context, chainID CHAIN_ID, enabledAddrs []ADDR, offset uint, limit uint) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
+ ret := _m.Called(ctx, chainID, enabledAddrs, offset, limit)
if len(ret) == 0 {
- panic("no return value specified for GetInProgressTxAttempts")
+ panic("no return value specified for GetAbandonedTransactionsByBatch")
}
- var r0 []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]
+ var r0 []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, ADDR, CHAIN_ID) ([]txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
- return rf(ctx, address, chainID)
+ if rf, ok := ret.Get(0).(func(context.Context, CHAIN_ID, []ADDR, uint, uint) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
+ return rf(ctx, chainID, enabledAddrs, offset, limit)
}
- if rf, ok := ret.Get(0).(func(context.Context, ADDR, CHAIN_ID) []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
- r0 = rf(ctx, address, chainID)
+ if rf, ok := ret.Get(0).(func(context.Context, CHAIN_ID, []ADDR, uint, uint) []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
+ r0 = rf(ctx, chainID, enabledAddrs, offset, limit)
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).([]txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE])
+ r0 = ret.Get(0).([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE])
}
}
- if rf, ok := ret.Get(1).(func(context.Context, ADDR, CHAIN_ID) error); ok {
- r1 = rf(ctx, address, chainID)
+ if rf, ok := ret.Get(1).(func(context.Context, CHAIN_ID, []ADDR, uint, uint) error); ok {
+ r1 = rf(ctx, chainID, enabledAddrs, offset, limit)
} else {
r1 = ret.Error(1)
}
@@ -730,29 +730,29 @@ func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) GetInProgre
return r0, r1
}
-// GetNonFatalTransactions provides a mock function with given fields: ctx, chainID
-func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) GetNonFatalTransactions(ctx context.Context, chainID CHAIN_ID) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
- ret := _m.Called(ctx, chainID)
+// GetInProgressTxAttempts provides a mock function with given fields: ctx, address, chainID
+func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) GetInProgressTxAttempts(ctx context.Context, address ADDR, chainID CHAIN_ID) ([]txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
+ ret := _m.Called(ctx, address, chainID)
if len(ret) == 0 {
- panic("no return value specified for GetNonFatalTransactions")
+ panic("no return value specified for GetInProgressTxAttempts")
}
- var r0 []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]
+ var r0 []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, CHAIN_ID) ([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
- return rf(ctx, chainID)
+ if rf, ok := ret.Get(0).(func(context.Context, ADDR, CHAIN_ID) ([]txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
+ return rf(ctx, address, chainID)
}
- if rf, ok := ret.Get(0).(func(context.Context, CHAIN_ID) []*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
- r0 = rf(ctx, chainID)
+ if rf, ok := ret.Get(0).(func(context.Context, ADDR, CHAIN_ID) []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
+ r0 = rf(ctx, address, chainID)
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).([]*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE])
+ r0 = ret.Get(0).([]txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE])
}
}
- if rf, ok := ret.Get(1).(func(context.Context, CHAIN_ID) error); ok {
- r1 = rf(ctx, chainID)
+ if rf, ok := ret.Get(1).(func(context.Context, ADDR, CHAIN_ID) error); ok {
+ r1 = rf(ctx, address, chainID)
} else {
r1 = ret.Error(1)
}
diff --git a/common/txmgr/types/tx_attempt_builder.go b/common/txmgr/types/tx_attempt_builder.go
index b242f73e6fc..54184733f0a 100644
--- a/common/txmgr/types/tx_attempt_builder.go
+++ b/common/txmgr/types/tx_attempt_builder.go
@@ -6,6 +6,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services"
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
+ "github.com/smartcontractkit/chainlink/v2/common/headtracker"
"github.com/smartcontractkit/chainlink/v2/common/types"
)
@@ -24,7 +25,7 @@ type TxAttemptBuilder[
] interface {
// interfaces for running the underlying estimator
services.Service
- types.HeadTrackable[HEAD, BLOCK_HASH]
+ headtracker.HeadTrackable[HEAD, BLOCK_HASH]
// NewTxAttempt builds a transaction using the configured transaction type and fee estimator (new estimation)
NewTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint64, retryable bool, err error)
diff --git a/common/txmgr/types/tx_store.go b/common/txmgr/types/tx_store.go
index f061f0ea628..bca2d1e3647 100644
--- a/common/txmgr/types/tx_store.go
+++ b/common/txmgr/types/tx_store.go
@@ -52,7 +52,7 @@ type TxStore[
// Find transactions with a non-null TxMeta field that was provided and a receipt block number greater than or equal to the one provided
FindTxesWithMetaFieldByReceiptBlockNum(ctx context.Context, metaField string, blockNum int64, chainID *big.Int) (tx []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
// Find transactions loaded with transaction attempts and receipts by transaction IDs and states
- FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []big.Int, states []TxState, chainID *big.Int) (tx []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
+ FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []int64, states []TxState, chainID *big.Int) (tx []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
}
// TransactionStore contains the persistence layer methods needed to manage Txs and TxAttempts
@@ -85,7 +85,7 @@ type TransactionStore[
FindEarliestUnconfirmedTxAttemptBlock(ctx context.Context, chainID CHAIN_ID) (null.Int, error)
GetTxInProgress(ctx context.Context, fromAddress ADDR) (etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
GetInProgressTxAttempts(ctx context.Context, address ADDR, chainID CHAIN_ID) (attempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
- GetNonFatalTransactions(ctx context.Context, chainID CHAIN_ID) (txs []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
+ GetAbandonedTransactionsByBatch(ctx context.Context, chainID CHAIN_ID, enabledAddrs []ADDR, offset, limit uint) (txs []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
GetTxByID(ctx context.Context, id int64) (tx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
HasInProgressTransaction(ctx context.Context, account ADDR, chainID CHAIN_ID) (exists bool, err error)
LoadTxAttempts(ctx context.Context, etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) error
diff --git a/common/types/chain.go b/common/types/chain.go
index c2c2011d8de..800f0d9fdc0 100644
--- a/common/types/chain.go
+++ b/common/types/chain.go
@@ -9,9 +9,6 @@ type Sequence interface {
Int64() int64 // needed for numeric sequence confirmation - to be removed with confirmation logic generalization: https://smartcontract-it.atlassian.net/browse/BCI-860
}
-// Generate the next usable sequence for a transaction
-type GenerateNextSequenceFunc[SEQ Sequence] func(prev SEQ) SEQ
-
// ID represents the base type, for any chain's ID.
// It should be convertible to a string, that can uniquely identify this chain
type ID fmt.Stringer
diff --git a/common/types/head_tracker.go b/common/types/head_tracker.go
deleted file mode 100644
index 83a2d7b8adb..00000000000
--- a/common/types/head_tracker.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package types
-
-import (
- "context"
-
- "github.com/smartcontractkit/chainlink-common/pkg/services"
-)
-
-// HeadTracker holds and stores the block experienced by a particular node in a thread safe manner.
-// Reconstitutes the last block number on reboot.
-//
-//go:generate mockery --quiet --name HeadTracker --output ../mocks/ --case=underscore
-type HeadTracker[H Head[BLOCK_HASH], BLOCK_HASH Hashable] interface {
- services.Service
- // Backfill given a head will fill in any missing heads up to latestFinalized
- Backfill(ctx context.Context, headWithChain, latestFinalized H) (err error)
- LatestChain() H
-}
-
-// HeadTrackable is implemented by the core txm,
-// to be able to receive head events from any chain.
-// Chain implementations should notify head events to the core txm via this interface.
-//
-//go:generate mockery --quiet --name HeadTrackable --output ./mocks/ --case=underscore
-type HeadTrackable[H Head[BLOCK_HASH], BLOCK_HASH Hashable] interface {
- // OnNewLongestChain sends a new head when it becomes available. Subscribers can recursively trace the parent
- // of the head to the finality depth back. If this is not possible (e.g. due to recent boot, backfill not complete
- // etc), users may get a shorter linked list. If there is a re-org, older blocks won't be sent to this function again.
- // But the new blocks from the re-org will be available in later blocks' parent linked list.
- OnNewLongestChain(ctx context.Context, head H)
-}
-
-// HeadSaver is an chain agnostic interface for saving and loading heads
-// Different chains will instantiate generic HeadSaver type with their native Head and BlockHash types.
-type HeadSaver[H Head[BLOCK_HASH], BLOCK_HASH Hashable] interface {
- // Save updates the latest block number, if indeed the latest, and persists
- // this number in case of reboot.
- Save(ctx context.Context, head H) error
- // Load loads latest heads up to latestFinalized - historyDepth, returns the latest chain.
- Load(ctx context.Context, latestFinalized int64) (H, error)
- // LatestChain returns the block header with the highest number that has been seen, or nil.
- LatestChain() H
- // Chain returns a head for the specified hash, or nil.
- Chain(hash BLOCK_HASH) H
- // MarkFinalized - marks matching block and all it's direct ancestors as finalized
- MarkFinalized(ctx context.Context, latestFinalized H) error
-}
-
-// HeadListener is a chain agnostic interface that manages connection of Client that receives heads from the blockchain node
-type HeadListener[H Head[BLOCK_HASH], BLOCK_HASH Hashable] interface {
- // ListenForNewHeads kicks off the listen loop (not thread safe)
- // done() must be executed upon leaving ListenForNewHeads()
- ListenForNewHeads(handleNewHead NewHeadHandler[H, BLOCK_HASH], done func())
-
- // ReceivingHeads returns true if the listener is receiving heads (thread safe)
- ReceivingHeads() bool
-
- // Connected returns true if the listener is connected (thread safe)
- Connected() bool
-
- // HealthReport returns report of errors within HeadListener
- HealthReport() map[string]error
-}
-
-// NewHeadHandler is a callback that handles incoming heads
-type NewHeadHandler[H Head[BLOCK_HASH], BLOCK_HASH Hashable] func(ctx context.Context, header H) error
-
-// HeadBroadcaster relays new Heads to all subscribers.
-//
-//go:generate mockery --quiet --name HeadBroadcaster --output ../mocks/ --case=underscore
-type HeadBroadcaster[H Head[BLOCK_HASH], BLOCK_HASH Hashable] interface {
- services.Service
- BroadcastNewLongestChain(H)
- HeadBroadcasterRegistry[H, BLOCK_HASH]
-}
-
-//go:generate mockery --quiet --name HeadBroadcaster --output ../mocks/ --case=underscore
-type HeadBroadcasterRegistry[H Head[BLOCK_HASH], BLOCK_HASH Hashable] interface {
- Subscribe(callback HeadTrackable[H, BLOCK_HASH]) (currentLongestChain H, unsubscribe func())
-}
diff --git a/common/types/subscription.go b/common/types/subscription.go
index 99247107bec..36d41ce1a20 100644
--- a/common/types/subscription.go
+++ b/common/types/subscription.go
@@ -4,7 +4,6 @@ package types
// delivered on a data channel.
// This is a generic interface for Subscription to represent used by clients.
-//go:generate mockery --quiet --name Subscription --output ./mocks/ --case=underscore
type Subscription interface {
// Unsubscribe cancels the sending of events to the data channel
// and closes the error channel.
diff --git a/contracts/.changeset/heavy-horses-greet.md b/contracts/.changeset/heavy-horses-greet.md
new file mode 100644
index 00000000000..51912232c26
--- /dev/null
+++ b/contracts/.changeset/heavy-horses-greet.md
@@ -0,0 +1,5 @@
+---
+"@chainlink/contracts": patch
+---
+
+support decimals #added
diff --git a/contracts/.changeset/mean-items-talk.md b/contracts/.changeset/mean-items-talk.md
new file mode 100644
index 00000000000..e03d49335ad
--- /dev/null
+++ b/contracts/.changeset/mean-items-talk.md
@@ -0,0 +1,5 @@
+---
+"@chainlink/contracts": patch
+---
+
+#wip Keystone custom error
diff --git a/contracts/.changeset/new-crews-deny.md b/contracts/.changeset/new-crews-deny.md
new file mode 100644
index 00000000000..170cc724344
--- /dev/null
+++ b/contracts/.changeset/new-crews-deny.md
@@ -0,0 +1,5 @@
+---
+"@chainlink/contracts": patch
+---
+
+vrfv2plus - account for num words in coordinator gas overhead in v2plus wrapper
diff --git a/contracts/.changeset/tasty-kangaroos-approve.md b/contracts/.changeset/tasty-kangaroos-approve.md
new file mode 100644
index 00000000000..006b3143bb6
--- /dev/null
+++ b/contracts/.changeset/tasty-kangaroos-approve.md
@@ -0,0 +1,5 @@
+---
+"@chainlink/contracts": patch
+---
+
+contracts work
diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile
index 4ec8057b975..38547ce3a57 100644
--- a/contracts/GNUmakefile
+++ b/contracts/GNUmakefile
@@ -73,18 +73,6 @@ wrappers-all: pnpmdep mockery abigen ## Recompiles solidity contracts and their
# go_generate contains a call to compile all contracts before generating wrappers
go generate ../core/gethwrappers/go_generate.go
-# Custom wrapper generation for OCR2VRF as their contracts do not exist in this repo
-.PHONY: go-solidity-wrappers-ocr2vrf
-go-solidity-wrappers-ocr2vrf: pnpmdep abigen ## Recompiles OCR2VRF solidity contracts and their go wrappers.
- ./scripts/native_solc_compile_all_ocr2vrf
- # replace the go:generate_disabled directive with the regular go:generate directive
- sed -i '' 's/go:generate_disabled/go:generate/g' ../core/gethwrappers/ocr2vrf/go_generate.go
- go generate ../core/gethwrappers/ocr2vrf
- go generate ../core/internal/mocks
- # put the go:generate_disabled directive back
- sed -i '' 's/go:generate/go:generate_disabled/g' ../core/gethwrappers/ocr2vrf/go_generate.go
-
-
help:
@echo ""
@echo " .__ .__ .__ .__ __"
diff --git a/contracts/gas-snapshots/keystone.gas-snapshot b/contracts/gas-snapshots/keystone.gas-snapshot
deleted file mode 100644
index 6797bd77e20..00000000000
--- a/contracts/gas-snapshots/keystone.gas-snapshot
+++ /dev/null
@@ -1,2 +0,0 @@
-KeystoneForwarderTest:test_abi_partial_decoding_works() (gas: 5123)
-KeystoneForwarderTest:test_it_works() (gas: 996215)
\ No newline at end of file
diff --git a/contracts/scripts/native_solc_compile_all_ocr2vrf b/contracts/scripts/native_solc_compile_all_ocr2vrf
deleted file mode 100755
index 755edd34f56..00000000000
--- a/contracts/scripts/native_solc_compile_all_ocr2vrf
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-echo " ┌──────────────────────────────────────────────┐"
-echo " │ Compiling OCR2 VRF contracts... │"
-echo " └──────────────────────────────────────────────┘"
-
-SOLC_VERSION="0.8.19"
-OPTIMIZE_RUNS=1000000
-# The VRF contracts are not contained in the `chainlink` repository.
-# Change me.
-FOLDER="ocr2vrf-origin"
-
-echo "Compiling OCR2VRF contracts..."
-
-SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
-ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1; cd ../../ && pwd -P )"
-python3 -m pip install --require-hashes -r "$SCRIPTPATH"/requirements.txt
-
-solc-select install $SOLC_VERSION
-solc-select use $SOLC_VERSION
-export SOLC_VERSION=$SOLC_VERSION
-
-
-compileContract () {
- local contract
- contract=$(basename "$1" ".sol")
-
- solc --overwrite --optimize --optimize-runs "$2" --metadata-hash none \
- -o "$ROOT"/contracts/solc/v0.8.19/"$contract" \
- --abi --bin \
- --allow-paths "$ROOT"/../$FOLDER/contracts \
- "$ROOT"/"$1"
-}
-
-# OCR2VRF
-compileContract ../$FOLDER/contracts/DKG.sol $OPTIMIZE_RUNS
-compileContract ../$FOLDER/contracts/VRFBeacon.sol $OPTIMIZE_RUNS
-compileContract ../$FOLDER/contracts/VRFCoordinator.sol 1
-compileContract ../$FOLDER/contracts/test/TestBeaconVRFConsumer.sol $OPTIMIZE_RUNS
-compileContract ../$FOLDER/contracts/test/LoadTestBeaconVRFConsumer.sol $OPTIMIZE_RUNS
diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol b/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol
index 8570c2130f2..90fdd82bfe7 100644
--- a/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol
+++ b/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol
@@ -1,4 +1,4 @@
-// abi-checksum: 0x0dcdf05637762c60acb4616a251bdc40d85ba134ec4b1b1e9f66646ba3132055
+// abi-checksum: 0x8860e73056784b47ec03fe67533e66ebf1a6d8e6e708c8046a71ecbe3b9334d9
// SPDX-License-Identifier: MIT
// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.6. SEE SOURCE BELOW. !!
pragma solidity ^0.8.4;
@@ -118,7 +118,6 @@ interface IAutomationRegistryMaster2_3 {
event UpkeepUnpaused(uint256 indexed id);
fallback() external payable;
function acceptOwnership() external;
- function addFunds(uint256 id, uint96 amount) external payable;
function fallbackTo() external view returns (address);
function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest);
function latestConfigDigestAndEpoch() external view returns (bool scanLogs, bytes32 configDigest, uint32 epoch);
@@ -167,6 +166,7 @@ interface IAutomationRegistryMaster2_3 {
) external returns (uint256 id);
function acceptUpkeepAdmin(uint256 id) external;
+ function addFunds(uint256 id, uint96 amount) external payable;
function checkCallback(
uint256 id,
bytes[] memory values,
@@ -306,6 +306,7 @@ interface AutomationRegistryBase2_3 {
uint32 gasFeePPB;
uint24 flatFeeMilliCents;
address priceFeed;
+ uint8 decimals;
uint256 fallbackPrice;
uint96 minSpend;
}
@@ -404,5 +405,5 @@ interface IAutomationV21PlusCommon {
// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
-[{"inputs":[{"internalType":"contract AutomationRegistryLogicA2_3","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[{"internalType":"uint256","name":"available","type":"uint256"},{"internalType":"uint256","name":"requested","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InsufficientLinkLiquidity","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidFeed","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"MustSettleOffchain","type":"error"},{"inputs":[],"name":"MustSettleOnchain","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyFinanceAdmin","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"indexed":false,"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"overrides","type":"tuple"}],"name":"BillingConfigOverridden","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"BillingConfigOverrideRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"indexed":false,"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"config","type":"tuple"}],"name":"BillingConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"assetAddress","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"payments","type":"uint256[]"}],"name":"NOPsSettledOffchain","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":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"},{"internalType":"contract IERC20[]","name":"billingTokens","type":"address[]"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig[]","name":"billingConfigs","type":"tuple[]"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_3","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"contract IERC20","name":"billingToken","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicC2_3","name":"logicC","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"removeBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"billingOverrides","type":"tuple"}],"name":"setBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"asset","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawERC20Fees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkUSDFeed","type":"address"},{"internalType":"address","name":"nativeUSDFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.PayoutMode","name":"payoutMode","type":"uint8"},{"internalType":"address","name":"wrappedNativeTokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableOffchainPayments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getBillingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getBillingTokenConfig","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBillingTokens","outputs":[{"internalType":"contract IERC20[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackNativePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHotVars","outputs":[{"components":[{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"reentrancyGuard","type":"bool"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.HotVars","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"contract IERC20","name":"billingToken","type":"address"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNativeUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumUpkeeps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPayoutMode","outputs":[{"internalType":"enum AutomationRegistryBase2_3.PayoutMode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"billingToken","type":"address"}],"name":"getReserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct IAutomationV21PlusCommon.StateLegacy","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct IAutomationV21PlusCommon.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStorage","outputs":[{"components":[{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"}],"internalType":"struct AutomationRegistryBase2_3.Storage","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmitCalldataFixedBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransmitCalldataPerSignerBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct IAutomationV21PlusCommon.UpkeepInfoLegacy","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrappedNativeTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleNOPsOffchain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"supportsBillingToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}]
+[{"inputs":[{"internalType":"contract AutomationRegistryLogicA2_3","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[{"internalType":"uint256","name":"available","type":"uint256"},{"internalType":"uint256","name":"requested","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InsufficientLinkLiquidity","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidFeed","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"MustSettleOffchain","type":"error"},{"inputs":[],"name":"MustSettleOnchain","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyFinanceAdmin","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"indexed":false,"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"overrides","type":"tuple"}],"name":"BillingConfigOverridden","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"BillingConfigOverrideRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20Metadata","name":"token","type":"address"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"indexed":false,"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"config","type":"tuple"}],"name":"BillingConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"assetAddress","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"payments","type":"uint256[]"}],"name":"NOPsSettledOffchain","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":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"},{"internalType":"contract IERC20Metadata[]","name":"billingTokens","type":"address[]"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig[]","name":"billingConfigs","type":"tuple[]"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_3","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicC2_3","name":"logicC","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"removeBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"billingOverrides","type":"tuple"}],"name":"setBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"asset","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawERC20Fees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkUSDFeed","type":"address"},{"internalType":"address","name":"nativeUSDFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.PayoutMode","name":"payoutMode","type":"uint8"},{"internalType":"address","name":"wrappedNativeTokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableOffchainPayments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getBillingToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"getBillingTokenConfig","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBillingTokens","outputs":[{"internalType":"contract IERC20Metadata[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackNativePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHotVars","outputs":[{"components":[{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"reentrancyGuard","type":"bool"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.HotVars","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNativeUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumUpkeeps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPayoutMode","outputs":[{"internalType":"enum AutomationRegistryBase2_3.PayoutMode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getReserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct IAutomationV21PlusCommon.StateLegacy","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct IAutomationV21PlusCommon.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStorage","outputs":[{"components":[{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"}],"internalType":"struct AutomationRegistryBase2_3.Storage","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmitCalldataFixedBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransmitCalldataPerSignerBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct IAutomationV21PlusCommon.UpkeepInfoLegacy","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrappedNativeTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleNOPsOffchain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"supportsBillingToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}]
*/
diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_3/IWrappedNative.sol b/contracts/src/v0.8/automation/dev/interfaces/v2_3/IWrappedNative.sol
index 5b03b2efeb1..dd371033023 100644
--- a/contracts/src/v0.8/automation/dev/interfaces/v2_3/IWrappedNative.sol
+++ b/contracts/src/v0.8/automation/dev/interfaces/v2_3/IWrappedNative.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
interface IWrappedNative is IERC20 {
function deposit() external payable;
diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistrar2_3.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistrar2_3.t.sol
index 850d2955a25..76b808d1f05 100644
--- a/contracts/src/v0.8/automation/dev/test/AutomationRegistrar2_3.t.sol
+++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistrar2_3.t.sol
@@ -4,7 +4,7 @@ pragma solidity 0.8.19;
import {BaseTest} from "./BaseTest.t.sol";
import {IAutomationRegistryMaster2_3} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol";
import {AutomationRegistrar2_3} from "../v2_3/AutomationRegistrar2_3.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {AutomationRegistryBase2_3 as AutoBase} from "../v2_3/AutomationRegistryBase2_3.sol";
import {IWrappedNative} from "../interfaces/v2_3/IWrappedNative.sol";
@@ -51,8 +51,8 @@ contract RegisterUpkeep is SetUp {
function testUSDToken_autoApproveOff_happy() external {
vm.startPrank(UPKEEP_ADMIN);
- uint96 amount = uint96(registrar.getMinimumRegistrationAmount(usdToken));
- usdToken.approve(address(registrar), amount);
+ uint96 amount = uint96(registrar.getMinimumRegistrationAmount(usdToken18));
+ usdToken18.approve(address(registrar), amount);
registrar.registerUpkeep(
AutomationRegistrar2_3.RegistrationParams({
@@ -61,7 +61,7 @@ contract RegisterUpkeep is SetUp {
adminAddress: UPKEEP_ADMIN,
gasLimit: 10_000,
triggerType: 0,
- billingToken: usdToken,
+ billingToken: usdToken18,
name: "foobar",
encryptedEmail: "",
checkData: bytes("check data"),
@@ -70,7 +70,7 @@ contract RegisterUpkeep is SetUp {
})
);
- assertEq(usdToken.balanceOf(address(registrar)), amount);
+ assertEq(usdToken18.balanceOf(address(registrar)), amount);
assertEq(registry.getNumUpkeeps(), 0);
}
@@ -106,8 +106,8 @@ contract RegisterUpkeep is SetUp {
registrar.setTriggerConfig(0, AutomationRegistrar2_3.AutoApproveType.ENABLED_ALL, 1000);
vm.startPrank(UPKEEP_ADMIN);
- uint96 amount = uint96(registrar.getMinimumRegistrationAmount(usdToken));
- usdToken.approve(address(registrar), amount);
+ uint96 amount = uint96(registrar.getMinimumRegistrationAmount(usdToken18));
+ usdToken18.approve(address(registrar), amount);
registrar.registerUpkeep(
AutomationRegistrar2_3.RegistrationParams({
@@ -116,7 +116,7 @@ contract RegisterUpkeep is SetUp {
adminAddress: UPKEEP_ADMIN,
gasLimit: 10_000,
triggerType: 0,
- billingToken: usdToken,
+ billingToken: usdToken18,
name: "foobar",
encryptedEmail: "",
checkData: bytes("check data"),
@@ -125,8 +125,8 @@ contract RegisterUpkeep is SetUp {
})
);
- assertEq(usdToken.balanceOf(address(registrar)), 0);
- assertEq(usdToken.balanceOf(address(registry)), amount);
+ assertEq(usdToken18.balanceOf(address(registrar)), 0);
+ assertEq(usdToken18.balanceOf(address(registry)), amount);
assertEq(registry.getNumUpkeeps(), 1);
}
@@ -211,4 +211,34 @@ contract RegisterUpkeep is SetUp {
assertEq(weth.balanceOf(address(registrar)), amount);
assertEq(registry.getNumUpkeeps(), 0);
}
+
+ function testLink_autoApproveOff_revertOnDuplicateEntry() external {
+ vm.startPrank(UPKEEP_ADMIN);
+
+ uint96 amount = uint96(registrar.getMinimumRegistrationAmount(IERC20(address(linkToken))));
+ linkToken.approve(address(registrar), amount * 2);
+
+ AutomationRegistrar2_3.RegistrationParams memory params = AutomationRegistrar2_3.RegistrationParams({
+ upkeepContract: address(TARGET1),
+ amount: amount,
+ adminAddress: UPKEEP_ADMIN,
+ gasLimit: 10_000,
+ triggerType: 0,
+ billingToken: IERC20(address(linkToken)),
+ name: "foobar",
+ encryptedEmail: "",
+ checkData: bytes("check data"),
+ triggerConfig: "",
+ offchainConfig: ""
+ });
+
+ registrar.registerUpkeep(params);
+
+ assertEq(linkToken.balanceOf(address(registrar)), amount);
+ assertEq(registry.getNumUpkeeps(), 0);
+
+ // attempt to register the same upkeep again
+ vm.expectRevert(AutomationRegistrar2_3.DuplicateEntry.selector);
+ registrar.registerUpkeep(params);
+ }
}
diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol
index 1f8fa42f36f..4d2cfbbec36 100644
--- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol
+++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol
@@ -7,7 +7,7 @@ import {AutomationRegistryBase2_3 as AutoBase} from "../v2_3/AutomationRegistryB
import {AutomationRegistrar2_3 as Registrar} from "../v2_3/AutomationRegistrar2_3.sol";
import {IAutomationRegistryMaster2_3 as Registry, AutomationRegistryBase2_3} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol";
import {ChainModuleBase} from "../../chains/ChainModuleBase.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IWrappedNative} from "../interfaces/v2_3/IWrappedNative.sol";
// forge test --match-path src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol
@@ -23,26 +23,30 @@ contract SetUp is BaseTest {
bytes internal constant offchainConfigBytes = abi.encode(1234, ZERO_ADDRESS);
uint256 linkUpkeepID;
- uint256 usdUpkeepID;
+ uint256 linkUpkeepID2; // 2 upkeeps use the same billing token (LINK) to test migration scenario
+ uint256 usdUpkeepID18; // 1 upkeep uses ERC20 token with 18 decimals
+ uint256 usdUpkeepID6; // 1 upkeep uses ERC20 token with 6 decimals
uint256 nativeUpkeepID;
function setUp() public virtual override {
super.setUp();
-
(registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN);
config = registry.getConfig();
vm.startPrank(OWNER);
linkToken.approve(address(registry), type(uint256).max);
- usdToken.approve(address(registry), type(uint256).max);
+ usdToken6.approve(address(registry), type(uint256).max);
+ usdToken18.approve(address(registry), type(uint256).max);
weth.approve(address(registry), type(uint256).max);
vm.startPrank(UPKEEP_ADMIN);
linkToken.approve(address(registry), type(uint256).max);
- usdToken.approve(address(registry), type(uint256).max);
+ usdToken6.approve(address(registry), type(uint256).max);
+ usdToken18.approve(address(registry), type(uint256).max);
weth.approve(address(registry), type(uint256).max);
vm.startPrank(STRANGER);
linkToken.approve(address(registry), type(uint256).max);
- usdToken.approve(address(registry), type(uint256).max);
+ usdToken6.approve(address(registry), type(uint256).max);
+ usdToken18.approve(address(registry), type(uint256).max);
weth.approve(address(registry), type(uint256).max);
vm.stopPrank();
@@ -57,12 +61,34 @@ contract SetUp is BaseTest {
""
);
- usdUpkeepID = registry.registerUpkeep(
+ linkUpkeepID2 = registry.registerUpkeep(
+ address(TARGET1),
+ config.maxPerformGas,
+ UPKEEP_ADMIN,
+ uint8(Trigger.CONDITION),
+ address(linkToken),
+ "",
+ "",
+ ""
+ );
+
+ usdUpkeepID18 = registry.registerUpkeep(
address(TARGET1),
config.maxPerformGas,
UPKEEP_ADMIN,
uint8(Trigger.CONDITION),
- address(usdToken),
+ address(usdToken18),
+ "",
+ "",
+ ""
+ );
+
+ usdUpkeepID6 = registry.registerUpkeep(
+ address(TARGET1),
+ config.maxPerformGas,
+ UPKEEP_ADMIN,
+ uint8(Trigger.CONDITION),
+ address(usdToken6),
"",
"",
""
@@ -81,7 +107,9 @@ contract SetUp is BaseTest {
vm.startPrank(OWNER);
registry.addFunds(linkUpkeepID, registry.getMinBalanceForUpkeep(linkUpkeepID));
- registry.addFunds(usdUpkeepID, registry.getMinBalanceForUpkeep(usdUpkeepID));
+ registry.addFunds(linkUpkeepID2, registry.getMinBalanceForUpkeep(linkUpkeepID2));
+ registry.addFunds(usdUpkeepID18, registry.getMinBalanceForUpkeep(usdUpkeepID18));
+ registry.addFunds(usdUpkeepID6, registry.getMinBalanceForUpkeep(usdUpkeepID6));
registry.addFunds(nativeUpkeepID, registry.getMinBalanceForUpkeep(nativeUpkeepID));
vm.stopPrank();
}
@@ -160,22 +188,22 @@ contract AddFunds is SetUp {
function test_movesFundFromCorrectToken() public {
vm.startPrank(UPKEEP_ADMIN);
- uint256 startBalanceLINK = linkToken.balanceOf(address(registry));
- uint256 startBalanceUSDToken = usdToken.balanceOf(address(registry));
+ uint256 startLINKRegistryBalance = linkToken.balanceOf(address(registry));
+ uint256 startUSDRegistryBalance = usdToken18.balanceOf(address(registry));
uint256 startLinkUpkeepBalance = registry.getBalance(linkUpkeepID);
- uint256 startUSDUpkeepBalance = registry.getBalance(usdUpkeepID);
+ uint256 startUSDUpkeepBalance = registry.getBalance(usdUpkeepID18);
registry.addFunds(linkUpkeepID, 1);
- assertEq(registry.getBalance(linkUpkeepID), startBalanceLINK + 1);
- assertEq(registry.getBalance(usdUpkeepID), startBalanceUSDToken);
- assertEq(linkToken.balanceOf(address(registry)), startLinkUpkeepBalance + 1);
- assertEq(usdToken.balanceOf(address(registry)), startUSDUpkeepBalance);
-
- registry.addFunds(usdUpkeepID, 2);
- assertEq(registry.getBalance(linkUpkeepID), startBalanceLINK + 1);
- assertEq(registry.getBalance(usdUpkeepID), startBalanceUSDToken + 2);
- assertEq(linkToken.balanceOf(address(registry)), startLinkUpkeepBalance + 1);
- assertEq(usdToken.balanceOf(address(registry)), startUSDUpkeepBalance + 2);
+ assertEq(registry.getBalance(linkUpkeepID), startLinkUpkeepBalance + 1);
+ assertEq(registry.getBalance(usdUpkeepID18), startUSDRegistryBalance);
+ assertEq(linkToken.balanceOf(address(registry)), startLINKRegistryBalance + 1);
+ assertEq(usdToken18.balanceOf(address(registry)), startUSDUpkeepBalance);
+
+ registry.addFunds(usdUpkeepID18, 2);
+ assertEq(registry.getBalance(linkUpkeepID), startLinkUpkeepBalance + 1);
+ assertEq(registry.getBalance(usdUpkeepID18), startUSDRegistryBalance + 2);
+ assertEq(linkToken.balanceOf(address(registry)), startLINKRegistryBalance + 1);
+ assertEq(usdToken18.balanceOf(address(registry)), startUSDUpkeepBalance + 2);
}
function test_emitsAnEvent() public {
@@ -245,10 +273,10 @@ contract Withdraw is SetUp {
}
function test_WithdrawERC20Fees_RespectsReserveAmount() public {
- assertEq(registry.getBalance(usdUpkeepID), registry.getReserveAmount(address(usdToken)));
+ assertEq(registry.getBalance(usdUpkeepID18), registry.getReserveAmount(address(usdToken18)));
vm.startPrank(FINANCE_ADMIN);
vm.expectRevert(abi.encodeWithSelector(Registry.InsufficientBalance.selector, 0, 1));
- registry.withdrawERC20Fees(address(usdToken), FINANCE_ADMIN, 1);
+ registry.withdrawERC20Fees(address(usdToken18), FINANCE_ADMIN, 1);
}
function test_WithdrawERC20Fees_RevertsWhen_AttemptingToWithdrawLINK() public {
@@ -260,35 +288,35 @@ contract Withdraw is SetUp {
}
function test_WithdrawERC20Fees_RevertsWhen_LinkAvailableForPaymentIsNegative() public {
- _transmit(usdUpkeepID, registry); // adds USD token to finance withdrawable, and gives NOPs a LINK balance
+ _transmit(usdUpkeepID18, registry); // adds USD token to finance withdrawable, and gives NOPs a LINK balance
require(registry.linkAvailableForPayment() < 0, "linkAvailableForPayment should be negative");
vm.expectRevert(Registry.InsufficientLinkLiquidity.selector);
vm.prank(FINANCE_ADMIN);
- registry.withdrawERC20Fees(address(usdToken), FINANCE_ADMIN, 1); // should revert
+ registry.withdrawERC20Fees(address(usdToken18), FINANCE_ADMIN, 1); // should revert
_mintLink(address(registry), uint256(registry.linkAvailableForPayment() * -10)); // top up LINK liquidity pool
vm.prank(FINANCE_ADMIN);
- registry.withdrawERC20Fees(address(usdToken), FINANCE_ADMIN, 1); // now finance can withdraw
+ registry.withdrawERC20Fees(address(usdToken18), FINANCE_ADMIN, 1); // now finance can withdraw
}
function testWithdrawERC20FeeSuccess() public {
// deposit excess USDToken to the registry (this goes to the "finance withdrawable" pool be default)
- uint256 startReserveAmount = registry.getReserveAmount(address(usdToken));
- uint256 startAmount = usdToken.balanceOf(address(registry));
- _mintERC20(address(registry), 1e10);
+ uint256 startReserveAmount = registry.getReserveAmount(address(usdToken18));
+ uint256 startAmount = usdToken18.balanceOf(address(registry));
+ _mintERC20_18Decimals(address(registry), 1e10);
// depositing shouldn't change reserve amount
- assertEq(registry.getReserveAmount(address(usdToken)), startReserveAmount);
+ assertEq(registry.getReserveAmount(address(usdToken18)), startReserveAmount);
vm.startPrank(FINANCE_ADMIN);
// try to withdraw 1 USDToken
- registry.withdrawERC20Fees(address(usdToken), aMockAddress, 1);
+ registry.withdrawERC20Fees(address(usdToken18), aMockAddress, 1);
vm.stopPrank();
- assertEq(usdToken.balanceOf(address(aMockAddress)), 1);
- assertEq(usdToken.balanceOf(address(registry)), startAmount + 1e10 - 1);
- assertEq(registry.getReserveAmount(address(usdToken)), startReserveAmount);
+ assertEq(usdToken18.balanceOf(address(aMockAddress)), 1);
+ assertEq(usdToken18.balanceOf(address(registry)), startAmount + 1e10 - 1);
+ assertEq(registry.getReserveAmount(address(usdToken18)), startReserveAmount);
}
}
@@ -330,7 +358,7 @@ contract SetConfig is SetUp {
(uint32 configCount, uint32 blockNumber, ) = registry.latestConfigDetails();
assertEq(configCount, 1);
- address billingTokenAddress = address(0x1111111111111111111111111111111111111111);
+ address billingTokenAddress = address(usdToken18);
address[] memory billingTokens = new address[](1);
billingTokens[0] = billingTokenAddress;
@@ -338,9 +366,10 @@ contract SetConfig is SetUp {
billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_000,
flatFeeMilliCents: 20_000,
- priceFeed: 0x2222222222222222222222222222222222222222,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 2_000_000_000, // $20
- minSpend: 100_000
+ minSpend: 100_000,
+ decimals: 18
});
bytes memory onchainConfigBytes = abi.encode(cfg);
@@ -389,7 +418,7 @@ contract SetConfig is SetUp {
AutomationRegistryBase2_3.BillingConfig memory config = registry.getBillingTokenConfig(billingTokenAddress);
assertEq(config.gasFeePPB, 5_000);
assertEq(config.flatFeeMilliCents, 20_000);
- assertEq(config.priceFeed, 0x2222222222222222222222222222222222222222);
+ assertEq(config.priceFeed, address(USDTOKEN_USD_FEED));
assertEq(config.minSpend, 100_000);
address[] memory tokens = registry.getBillingTokens();
@@ -400,8 +429,8 @@ contract SetConfig is SetUp {
(uint32 configCount, , ) = registry.latestConfigDetails();
assertEq(configCount, 1);
- address billingTokenAddress1 = address(0x1111111111111111111111111111111111111111);
- address billingTokenAddress2 = address(0x1111111111111111111111111111111111111112);
+ address billingTokenAddress1 = address(linkToken);
+ address billingTokenAddress2 = address(usdToken18);
address[] memory billingTokens = new address[](2);
billingTokens[0] = billingTokenAddress1;
billingTokens[1] = billingTokenAddress2;
@@ -410,16 +439,18 @@ contract SetConfig is SetUp {
billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_001,
flatFeeMilliCents: 20_001,
- priceFeed: 0x2222222222222222222222222222222222222221,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 100,
- minSpend: 100
+ minSpend: 100,
+ decimals: 18
});
billingConfigs[1] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_002,
flatFeeMilliCents: 20_002,
- priceFeed: 0x2222222222222222222222222222222222222222,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 200,
- minSpend: 200
+ minSpend: 200,
+ decimals: 18
});
bytes memory onchainConfigBytesWithBilling = abi.encode(cfg, billingTokens, billingConfigs);
@@ -442,14 +473,14 @@ contract SetConfig is SetUp {
AutomationRegistryBase2_3.BillingConfig memory config1 = registry.getBillingTokenConfig(billingTokenAddress1);
assertEq(config1.gasFeePPB, 5_001);
assertEq(config1.flatFeeMilliCents, 20_001);
- assertEq(config1.priceFeed, 0x2222222222222222222222222222222222222221);
+ assertEq(config1.priceFeed, address(USDTOKEN_USD_FEED));
assertEq(config1.fallbackPrice, 100);
assertEq(config1.minSpend, 100);
AutomationRegistryBase2_3.BillingConfig memory config2 = registry.getBillingTokenConfig(billingTokenAddress2);
assertEq(config2.gasFeePPB, 5_002);
assertEq(config2.flatFeeMilliCents, 20_002);
- assertEq(config2.priceFeed, 0x2222222222222222222222222222222222222222);
+ assertEq(config2.priceFeed, address(USDTOKEN_USD_FEED));
assertEq(config2.fallbackPrice, 200);
assertEq(config2.minSpend, 200);
@@ -462,7 +493,7 @@ contract SetConfig is SetUp {
assertEq(configCount, 1);
// BillingConfig1
- address billingTokenAddress1 = address(0x1111111111111111111111111111111111111111);
+ address billingTokenAddress1 = address(usdToken18);
address[] memory billingTokens1 = new address[](1);
billingTokens1[0] = billingTokenAddress1;
@@ -470,15 +501,16 @@ contract SetConfig is SetUp {
billingConfigs1[0] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_001,
flatFeeMilliCents: 20_001,
- priceFeed: 0x2222222222222222222222222222222222222221,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 100,
- minSpend: 100
+ minSpend: 100,
+ decimals: 18
});
bytes memory onchainConfigBytesWithBilling1 = abi.encode(cfg, billingTokens1, billingConfigs1);
// BillingConfig2
- address billingTokenAddress2 = address(0x1111111111111111111111111111111111111112);
+ address billingTokenAddress2 = address(usdToken18);
address[] memory billingTokens2 = new address[](1);
billingTokens2[0] = billingTokenAddress2;
@@ -486,9 +518,10 @@ contract SetConfig is SetUp {
billingConfigs2[0] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_002,
flatFeeMilliCents: 20_002,
- priceFeed: 0x2222222222222222222222222222222222222222,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 200,
- minSpend: 200
+ minSpend: 200,
+ decimals: 18
});
bytes memory onchainConfigBytesWithBilling2 = abi.encode(cfg, billingTokens2, billingConfigs2);
@@ -522,7 +555,7 @@ contract SetConfig is SetUp {
AutomationRegistryBase2_3.BillingConfig memory config2 = registry.getBillingTokenConfig(billingTokenAddress2);
assertEq(config2.gasFeePPB, 5_002);
assertEq(config2.flatFeeMilliCents, 20_002);
- assertEq(config2.priceFeed, 0x2222222222222222222222222222222222222222);
+ assertEq(config2.priceFeed, address(USDTOKEN_USD_FEED));
assertEq(config2.fallbackPrice, 200);
assertEq(config2.minSpend, 200);
@@ -534,8 +567,8 @@ contract SetConfig is SetUp {
(uint32 configCount, , ) = registry.latestConfigDetails();
assertEq(configCount, 1);
- address billingTokenAddress1 = address(0x1111111111111111111111111111111111111111);
- address billingTokenAddress2 = address(0x1111111111111111111111111111111111111111);
+ address billingTokenAddress1 = address(linkToken);
+ address billingTokenAddress2 = address(linkToken);
address[] memory billingTokens = new address[](2);
billingTokens[0] = billingTokenAddress1;
billingTokens[1] = billingTokenAddress2;
@@ -544,16 +577,18 @@ contract SetConfig is SetUp {
billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_001,
flatFeeMilliCents: 20_001,
- priceFeed: 0x2222222222222222222222222222222222222221,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 100,
- minSpend: 100
+ minSpend: 100,
+ decimals: 18
});
billingConfigs[1] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_002,
flatFeeMilliCents: 20_002,
- priceFeed: 0x2222222222222222222222222222222222222222,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 200,
- minSpend: 200
+ minSpend: 200,
+ decimals: 18
});
bytes memory onchainConfigBytesWithBilling = abi.encode(cfg, billingTokens, billingConfigs);
@@ -578,9 +613,10 @@ contract SetConfig is SetUp {
billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_000,
flatFeeMilliCents: 20_000,
- priceFeed: 0x2222222222222222222222222222222222222222,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 2_000_000_000, // $20
- minSpend: 100_000
+ minSpend: 100_000,
+ decimals: 18
});
// deploy registry with OFF_CHAIN payout mode
@@ -599,13 +635,40 @@ contract SetConfig is SetUp {
);
}
+ function testSetConfigRevertDueToInvalidDecimals() public {
+ address[] memory billingTokens = new address[](1);
+ billingTokens[0] = address(linkToken);
+
+ AutomationRegistryBase2_3.BillingConfig[] memory billingConfigs = new AutomationRegistryBase2_3.BillingConfig[](1);
+ billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({
+ gasFeePPB: 5_000,
+ flatFeeMilliCents: 20_000,
+ priceFeed: address(USDTOKEN_USD_FEED),
+ fallbackPrice: 2_000_000_000, // $20
+ minSpend: 100_000,
+ decimals: 6 // link token should have 18 decimals
+ });
+
+ vm.expectRevert(abi.encodeWithSelector(Registry.InvalidToken.selector));
+ registry.setConfigTypeSafe(
+ SIGNERS,
+ TRANSMITTERS,
+ F,
+ cfg,
+ OFFCHAIN_CONFIG_VERSION,
+ offchainConfigBytes,
+ billingTokens,
+ billingConfigs
+ );
+ }
+
function testSetConfigWithNewTransmittersSuccess() public {
registry = deployRegistry(AutoBase.PayoutMode.OFF_CHAIN);
(uint32 configCount, uint32 blockNumber, ) = registry.latestConfigDetails();
assertEq(configCount, 0);
- address billingTokenAddress = address(0x1111111111111111111111111111111111111111);
+ address billingTokenAddress = address(usdToken18);
address[] memory billingTokens = new address[](1);
billingTokens[0] = billingTokenAddress;
@@ -613,9 +676,10 @@ contract SetConfig is SetUp {
billingConfigs[0] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 5_000,
flatFeeMilliCents: 20_000,
- priceFeed: 0x2222222222222222222222222222222222222222,
+ priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 2_000_000_000, // $20
- minSpend: 100_000
+ minSpend: 100_000,
+ decimals: 18
});
bytes memory onchainConfigBytes = abi.encode(cfg);
@@ -777,10 +841,10 @@ contract NOPsSettlement is SetUp {
(Registry registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN);
// register an upkeep and add funds
- uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken), "", "", "");
- _mintERC20(UPKEEP_ADMIN, 1e20);
+ uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", "");
+ _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20);
vm.startPrank(UPKEEP_ADMIN);
- usdToken.approve(address(registry), 1e20);
+ usdToken18.approve(address(registry), 1e20);
registry.addFunds(id, 1e20);
// manually create a transmit so transmitters earn some rewards
@@ -818,10 +882,10 @@ contract NOPsSettlement is SetUp {
(Registry registry, Registrar registrar) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN);
// register an upkeep and add funds
- uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken), "", "", "");
- _mintERC20(UPKEEP_ADMIN, 1e20);
+ uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", "");
+ _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20);
vm.startPrank(UPKEEP_ADMIN);
- usdToken.approve(address(registry), 1e20);
+ usdToken18.approve(address(registry), 1e20);
registry.addFunds(id, 1e20);
// manually create a transmit so TRANSMITTERS earn some rewards
@@ -930,10 +994,10 @@ contract NOPsSettlement is SetUp {
(Registry registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN);
// register an upkeep and add funds
- uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken), "", "", "");
- _mintERC20(UPKEEP_ADMIN, 1e20);
+ uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", "");
+ _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20);
vm.startPrank(UPKEEP_ADMIN);
- usdToken.approve(address(registry), 1e20);
+ usdToken18.approve(address(registry), 1e20);
registry.addFunds(id, 1e20);
// manually create a transmit so transmitters earn some rewards
@@ -968,10 +1032,10 @@ contract NOPsSettlement is SetUp {
(Registry registry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.OFF_CHAIN);
// register an upkeep and add funds
- uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken), "", "", "");
- _mintERC20(UPKEEP_ADMIN, 1e20);
+ uint256 id = registry.registerUpkeep(address(TARGET1), 1000000, UPKEEP_ADMIN, 0, address(usdToken18), "", "", "");
+ _mintERC20_18Decimals(UPKEEP_ADMIN, 1e20);
vm.startPrank(UPKEEP_ADMIN);
- usdToken.approve(address(registry), 1e20);
+ usdToken18.approve(address(registry), 1e20);
registry.addFunds(id, 1e20);
// manually call transmit so transmitters earn some rewards
@@ -1012,26 +1076,30 @@ contract NOPsSettlement is SetUp {
function _configureWithNewTransmitters(Registry registry, Registrar registrar) internal {
IERC20[] memory billingTokens = new IERC20[](1);
- billingTokens[0] = IERC20(address(usdToken));
+ billingTokens[0] = IERC20(address(usdToken18));
+
uint256[] memory minRegistrationFees = new uint256[](billingTokens.length);
- minRegistrationFees[0] = 100000000000000000000; // 100 USD
+ minRegistrationFees[0] = 100e18; // 100 USD
+
address[] memory billingTokenAddresses = new address[](billingTokens.length);
for (uint256 i = 0; i < billingTokens.length; i++) {
billingTokenAddresses[i] = address(billingTokens[i]);
}
+
AutomationRegistryBase2_3.BillingConfig[]
memory billingTokenConfigs = new AutomationRegistryBase2_3.BillingConfig[](billingTokens.length);
billingTokenConfigs[0] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: 10_000_000, // 15%
flatFeeMilliCents: 2_000, // 2 cents
priceFeed: address(USDTOKEN_USD_FEED),
- fallbackPrice: 100_000_000, // $1
- minSpend: 1000000000000000000 // 1 USD
+ fallbackPrice: 1e8, // $1
+ minSpend: 1e18, // 1 USD
+ decimals: 18
});
- address[] memory registrars;
- registrars = new address[](1);
+ address[] memory registrars = new address[](1);
registrars[0] = address(registrar);
+
AutomationRegistryBase2_3.OnchainConfig memory cfg = AutomationRegistryBase2_3.OnchainConfig({
checkGasLimit: 5_000_000,
stalenessSeconds: 90_000,
@@ -1050,6 +1118,7 @@ contract NOPsSettlement is SetUp {
reorgProtectionEnabled: true,
financeAdmin: FINANCE_ADMIN
});
+
registry.setConfigTypeSafe(
SIGNERS,
NEW_TRANSMITTERS,
@@ -1060,6 +1129,7 @@ contract NOPsSettlement is SetUp {
billingTokenAddresses,
billingTokenConfigs
);
+
registry.setPayees(NEW_PAYEES);
}
}
@@ -1227,7 +1297,7 @@ contract OnTokenTransfer is SetUp {
function test_RevertsWhen_TheUpkeepDoesNotUseLINKAsItsBillingToken() public {
vm.startPrank(address(linkToken));
vm.expectRevert(Registry.InvalidToken.selector);
- registry.onTokenTransfer(UPKEEP_ADMIN, 100, abi.encode(usdUpkeepID));
+ registry.onTokenTransfer(UPKEEP_ADMIN, 100, abi.encode(usdUpkeepID18));
}
function test_Happy() public {
@@ -1239,20 +1309,42 @@ contract OnTokenTransfer is SetUp {
}
contract GetMinBalanceForUpkeep is SetUp {
- function test_accountsForFlatFee() public {
+ function test_accountsForFlatFee_with18Decimals() public {
+ // set fee to 0
+ AutomationRegistryBase2_3.BillingConfig memory usdTokenConfig = registry.getBillingTokenConfig(address(usdToken18));
+ usdTokenConfig.flatFeeMilliCents = 0;
+ _updateBillingTokenConfig(registry, address(usdToken18), usdTokenConfig);
+
+ uint256 minBalanceBefore = registry.getMinBalanceForUpkeep(usdUpkeepID18);
+
+ // set fee to non-zero
+ usdTokenConfig.flatFeeMilliCents = 100;
+ _updateBillingTokenConfig(registry, address(usdToken18), usdTokenConfig);
+
+ uint256 minBalanceAfter = registry.getMinBalanceForUpkeep(usdUpkeepID18);
+ assertEq(
+ minBalanceAfter,
+ minBalanceBefore + ((uint256(usdTokenConfig.flatFeeMilliCents) * 1e13) / 10 ** (18 - usdTokenConfig.decimals))
+ );
+ }
+
+ function test_accountsForFlatFee_with6Decimals() public {
// set fee to 0
- AutomationRegistryBase2_3.BillingConfig memory usdTokenConfig = registry.getBillingTokenConfig(address(usdToken));
+ AutomationRegistryBase2_3.BillingConfig memory usdTokenConfig = registry.getBillingTokenConfig(address(usdToken6));
usdTokenConfig.flatFeeMilliCents = 0;
- _updateBillingTokenConfig(registry, address(usdToken), usdTokenConfig);
+ _updateBillingTokenConfig(registry, address(usdToken6), usdTokenConfig);
- uint256 minBalanceBefore = registry.getMinBalanceForUpkeep(usdUpkeepID);
+ uint256 minBalanceBefore = registry.getMinBalanceForUpkeep(usdUpkeepID6);
// set fee to non-zero
usdTokenConfig.flatFeeMilliCents = 100;
- _updateBillingTokenConfig(registry, address(usdToken), usdTokenConfig);
+ _updateBillingTokenConfig(registry, address(usdToken6), usdTokenConfig);
- uint256 minBalanceAfter = registry.getMinBalanceForUpkeep(usdUpkeepID);
- assertEq(minBalanceAfter, minBalanceBefore + (uint256(usdTokenConfig.flatFeeMilliCents) * 1e13));
+ uint256 minBalanceAfter = registry.getMinBalanceForUpkeep(usdUpkeepID6);
+ assertEq(
+ minBalanceAfter,
+ minBalanceBefore + ((uint256(usdTokenConfig.flatFeeMilliCents) * 1e13) / 10 ** (18 - usdTokenConfig.decimals))
+ );
}
}
@@ -1328,29 +1420,29 @@ contract Transmit is SetUp {
function test_handlesMixedBatchOfBillingTokens() external {
uint256[] memory prevUpkeepBalances = new uint256[](3);
prevUpkeepBalances[0] = registry.getBalance(linkUpkeepID);
- prevUpkeepBalances[1] = registry.getBalance(usdUpkeepID);
+ prevUpkeepBalances[1] = registry.getBalance(usdUpkeepID18);
prevUpkeepBalances[2] = registry.getBalance(nativeUpkeepID);
uint256[] memory prevTokenBalances = new uint256[](3);
prevTokenBalances[0] = linkToken.balanceOf(address(registry));
- prevTokenBalances[1] = usdToken.balanceOf(address(registry));
+ prevTokenBalances[1] = usdToken18.balanceOf(address(registry));
prevTokenBalances[2] = weth.balanceOf(address(registry));
uint256[] memory prevReserveBalances = new uint256[](3);
prevReserveBalances[0] = registry.getReserveAmount(address(linkToken));
- prevReserveBalances[1] = registry.getReserveAmount(address(usdToken));
+ prevReserveBalances[1] = registry.getReserveAmount(address(usdToken18));
prevReserveBalances[2] = registry.getReserveAmount(address(weth));
uint256[] memory upkeepIDs = new uint256[](3);
upkeepIDs[0] = linkUpkeepID;
- upkeepIDs[1] = usdUpkeepID;
+ upkeepIDs[1] = usdUpkeepID18;
upkeepIDs[2] = nativeUpkeepID;
// do the thing
_transmit(upkeepIDs, registry);
// assert upkeep balances have decreased
require(prevUpkeepBalances[0] > registry.getBalance(linkUpkeepID), "link upkeep balance should have decreased");
- require(prevUpkeepBalances[1] > registry.getBalance(usdUpkeepID), "usd upkeep balance should have decreased");
+ require(prevUpkeepBalances[1] > registry.getBalance(usdUpkeepID18), "usd upkeep balance should have decreased");
require(prevUpkeepBalances[2] > registry.getBalance(nativeUpkeepID), "native upkeep balance should have decreased");
// assert token balances have not changed
assertEq(prevTokenBalances[0], linkToken.balanceOf(address(registry)));
- assertEq(prevTokenBalances[1], usdToken.balanceOf(address(registry)));
+ assertEq(prevTokenBalances[1], usdToken18.balanceOf(address(registry)));
assertEq(prevTokenBalances[2], weth.balanceOf(address(registry)));
// assert reserve amounts have adjusted accordingly
require(
@@ -1358,7 +1450,7 @@ contract Transmit is SetUp {
"usd reserve amount should have increased"
); // link reserve amount increases in value equal to the decrease of the other reserve amounts
require(
- prevReserveBalances[1] > registry.getReserveAmount(address(usdToken)),
+ prevReserveBalances[1] > registry.getReserveAmount(address(usdToken18)),
"usd reserve amount should have decreased"
);
require(
@@ -1379,7 +1471,8 @@ contract MigrateReceive is SetUp {
super.setUp();
(newRegistry, ) = deployAndConfigureRegistryAndRegistrar(AutoBase.PayoutMode.ON_CHAIN);
idsToMigrate.push(linkUpkeepID);
- idsToMigrate.push(usdUpkeepID);
+ idsToMigrate.push(linkUpkeepID2);
+ idsToMigrate.push(usdUpkeepID18);
idsToMigrate.push(nativeUpkeepID);
registry.setPeerRegistryMigrationPermission(address(newRegistry), 1);
newRegistry.setPeerRegistryMigrationPermission(address(registry), 2);
@@ -1435,89 +1528,109 @@ contract MigrateReceive is SetUp {
vm.startPrank(UPKEEP_ADMIN);
// add some changes in upkeep data to the mix
- registry.pauseUpkeep(usdUpkeepID);
+ registry.pauseUpkeep(usdUpkeepID18);
registry.setUpkeepTriggerConfig(linkUpkeepID, randomBytes(100));
registry.setUpkeepCheckData(nativeUpkeepID, randomBytes(25));
// record previous state
- uint256[] memory prevUpkeepBalances = new uint256[](3);
+ uint256[] memory prevUpkeepBalances = new uint256[](4);
prevUpkeepBalances[0] = registry.getBalance(linkUpkeepID);
- prevUpkeepBalances[1] = registry.getBalance(usdUpkeepID);
- prevUpkeepBalances[2] = registry.getBalance(nativeUpkeepID);
+ prevUpkeepBalances[1] = registry.getBalance(linkUpkeepID2);
+ prevUpkeepBalances[2] = registry.getBalance(usdUpkeepID18);
+ prevUpkeepBalances[3] = registry.getBalance(nativeUpkeepID);
uint256[] memory prevReserveBalances = new uint256[](3);
prevReserveBalances[0] = registry.getReserveAmount(address(linkToken));
- prevReserveBalances[1] = registry.getReserveAmount(address(usdToken));
+ prevReserveBalances[1] = registry.getReserveAmount(address(usdToken18));
prevReserveBalances[2] = registry.getReserveAmount(address(weth));
uint256[] memory prevTokenBalances = new uint256[](3);
prevTokenBalances[0] = linkToken.balanceOf(address(registry));
- prevTokenBalances[1] = usdToken.balanceOf(address(registry));
+ prevTokenBalances[1] = usdToken18.balanceOf(address(registry));
prevTokenBalances[2] = weth.balanceOf(address(registry));
- bytes[] memory prevUpkeepData = new bytes[](3);
+ bytes[] memory prevUpkeepData = new bytes[](4);
prevUpkeepData[0] = abi.encode(registry.getUpkeep(linkUpkeepID));
- prevUpkeepData[1] = abi.encode(registry.getUpkeep(usdUpkeepID));
- prevUpkeepData[2] = abi.encode(registry.getUpkeep(nativeUpkeepID));
- bytes[] memory prevUpkeepTriggerData = new bytes[](3);
+ prevUpkeepData[1] = abi.encode(registry.getUpkeep(linkUpkeepID2));
+ prevUpkeepData[2] = abi.encode(registry.getUpkeep(usdUpkeepID18));
+ prevUpkeepData[3] = abi.encode(registry.getUpkeep(nativeUpkeepID));
+ bytes[] memory prevUpkeepTriggerData = new bytes[](4);
prevUpkeepTriggerData[0] = registry.getUpkeepTriggerConfig(linkUpkeepID);
- prevUpkeepTriggerData[1] = registry.getUpkeepTriggerConfig(usdUpkeepID);
- prevUpkeepTriggerData[2] = registry.getUpkeepTriggerConfig(nativeUpkeepID);
+ prevUpkeepTriggerData[1] = registry.getUpkeepTriggerConfig(linkUpkeepID2);
+ prevUpkeepTriggerData[2] = registry.getUpkeepTriggerConfig(usdUpkeepID18);
+ prevUpkeepTriggerData[3] = registry.getUpkeepTriggerConfig(nativeUpkeepID);
// event expectations
vm.expectEmit(address(registry));
emit UpkeepMigrated(linkUpkeepID, prevUpkeepBalances[0], address(newRegistry));
vm.expectEmit(address(registry));
- emit UpkeepMigrated(usdUpkeepID, prevUpkeepBalances[1], address(newRegistry));
+ emit UpkeepMigrated(linkUpkeepID2, prevUpkeepBalances[1], address(newRegistry));
+ vm.expectEmit(address(registry));
+ emit UpkeepMigrated(usdUpkeepID18, prevUpkeepBalances[2], address(newRegistry));
vm.expectEmit(address(registry));
- emit UpkeepMigrated(nativeUpkeepID, prevUpkeepBalances[2], address(newRegistry));
+ emit UpkeepMigrated(nativeUpkeepID, prevUpkeepBalances[3], address(newRegistry));
vm.expectEmit(address(newRegistry));
emit UpkeepReceived(linkUpkeepID, prevUpkeepBalances[0], address(registry));
vm.expectEmit(address(newRegistry));
- emit UpkeepReceived(usdUpkeepID, prevUpkeepBalances[1], address(registry));
+ emit UpkeepReceived(linkUpkeepID2, prevUpkeepBalances[1], address(registry));
+ vm.expectEmit(address(newRegistry));
+ emit UpkeepReceived(usdUpkeepID18, prevUpkeepBalances[2], address(registry));
vm.expectEmit(address(newRegistry));
- emit UpkeepReceived(nativeUpkeepID, prevUpkeepBalances[2], address(registry));
+ emit UpkeepReceived(nativeUpkeepID, prevUpkeepBalances[3], address(registry));
// do the thing
registry.migrateUpkeeps(idsToMigrate, address(newRegistry));
// assert upkeep balances have been migrated
assertEq(registry.getBalance(linkUpkeepID), 0);
- assertEq(registry.getBalance(usdUpkeepID), 0);
+ assertEq(registry.getBalance(linkUpkeepID2), 0);
+ assertEq(registry.getBalance(usdUpkeepID18), 0);
assertEq(registry.getBalance(nativeUpkeepID), 0);
assertEq(newRegistry.getBalance(linkUpkeepID), prevUpkeepBalances[0]);
- assertEq(newRegistry.getBalance(usdUpkeepID), prevUpkeepBalances[1]);
- assertEq(newRegistry.getBalance(nativeUpkeepID), prevUpkeepBalances[2]);
+ assertEq(newRegistry.getBalance(linkUpkeepID2), prevUpkeepBalances[1]);
+ assertEq(newRegistry.getBalance(usdUpkeepID18), prevUpkeepBalances[2]);
+ assertEq(newRegistry.getBalance(nativeUpkeepID), prevUpkeepBalances[3]);
// assert reserve balances have been adjusted
- assertEq(newRegistry.getReserveAmount(address(linkToken)), newRegistry.getBalance(linkUpkeepID));
- assertEq(newRegistry.getReserveAmount(address(usdToken)), newRegistry.getBalance(usdUpkeepID));
+ assertEq(
+ newRegistry.getReserveAmount(address(linkToken)),
+ newRegistry.getBalance(linkUpkeepID) + newRegistry.getBalance(linkUpkeepID2)
+ );
+ assertEq(newRegistry.getReserveAmount(address(usdToken18)), newRegistry.getBalance(usdUpkeepID18));
assertEq(newRegistry.getReserveAmount(address(weth)), newRegistry.getBalance(nativeUpkeepID));
assertEq(
newRegistry.getReserveAmount(address(linkToken)),
prevReserveBalances[0] - registry.getReserveAmount(address(linkToken))
);
assertEq(
- newRegistry.getReserveAmount(address(usdToken)),
- prevReserveBalances[1] - registry.getReserveAmount(address(usdToken))
+ newRegistry.getReserveAmount(address(usdToken18)),
+ prevReserveBalances[1] - registry.getReserveAmount(address(usdToken18))
);
assertEq(
newRegistry.getReserveAmount(address(weth)),
prevReserveBalances[2] - registry.getReserveAmount(address(weth))
);
- // assert token have been transfered
- assertEq(linkToken.balanceOf(address(newRegistry)), newRegistry.getBalance(linkUpkeepID));
- assertEq(usdToken.balanceOf(address(newRegistry)), newRegistry.getBalance(usdUpkeepID));
+ // assert token have been transferred
+ assertEq(
+ linkToken.balanceOf(address(newRegistry)),
+ newRegistry.getBalance(linkUpkeepID) + newRegistry.getBalance(linkUpkeepID2)
+ );
+ assertEq(usdToken18.balanceOf(address(newRegistry)), newRegistry.getBalance(usdUpkeepID18));
assertEq(weth.balanceOf(address(newRegistry)), newRegistry.getBalance(nativeUpkeepID));
assertEq(linkToken.balanceOf(address(registry)), prevTokenBalances[0] - linkToken.balanceOf(address(newRegistry)));
- assertEq(usdToken.balanceOf(address(registry)), prevTokenBalances[1] - usdToken.balanceOf(address(newRegistry)));
+ assertEq(
+ usdToken18.balanceOf(address(registry)),
+ prevTokenBalances[1] - usdToken18.balanceOf(address(newRegistry))
+ );
assertEq(weth.balanceOf(address(registry)), prevTokenBalances[2] - weth.balanceOf(address(newRegistry)));
// assert upkeep data matches
assertEq(prevUpkeepData[0], abi.encode(newRegistry.getUpkeep(linkUpkeepID)));
- assertEq(prevUpkeepData[1], abi.encode(newRegistry.getUpkeep(usdUpkeepID)));
- assertEq(prevUpkeepData[2], abi.encode(newRegistry.getUpkeep(nativeUpkeepID)));
+ assertEq(prevUpkeepData[1], abi.encode(newRegistry.getUpkeep(linkUpkeepID2)));
+ assertEq(prevUpkeepData[2], abi.encode(newRegistry.getUpkeep(usdUpkeepID18)));
+ assertEq(prevUpkeepData[3], abi.encode(newRegistry.getUpkeep(nativeUpkeepID)));
assertEq(prevUpkeepTriggerData[0], newRegistry.getUpkeepTriggerConfig(linkUpkeepID));
- assertEq(prevUpkeepTriggerData[1], newRegistry.getUpkeepTriggerConfig(usdUpkeepID));
- assertEq(prevUpkeepTriggerData[2], newRegistry.getUpkeepTriggerConfig(nativeUpkeepID));
+ assertEq(prevUpkeepTriggerData[1], newRegistry.getUpkeepTriggerConfig(linkUpkeepID2));
+ assertEq(prevUpkeepTriggerData[2], newRegistry.getUpkeepTriggerConfig(usdUpkeepID18));
+ assertEq(prevUpkeepTriggerData[3], newRegistry.getUpkeepTriggerConfig(nativeUpkeepID));
vm.stopPrank();
}
diff --git a/contracts/src/v0.8/automation/dev/test/BaseTest.t.sol b/contracts/src/v0.8/automation/dev/test/BaseTest.t.sol
index eae07a8bab7..5ae9a29fc15 100644
--- a/contracts/src/v0.8/automation/dev/test/BaseTest.t.sol
+++ b/contracts/src/v0.8/automation/dev/test/BaseTest.t.sol
@@ -5,6 +5,7 @@ import "forge-std/Test.sol";
import {LinkToken} from "../../../shared/token/ERC677/LinkToken.sol";
import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol";
+import {ERC20Mock6Decimals} from "../../mocks/ERC20Mock6Decimals.sol";
import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol";
import {AutomationForwarderLogic} from "../../AutomationForwarderLogic.sol";
import {UpkeepTranscoder5_0 as Transcoder} from "../v2_3/UpkeepTranscoder5_0.sol";
@@ -16,7 +17,7 @@ import {AutomationRegistryLogicC2_3} from "../v2_3/AutomationRegistryLogicC2_3.s
import {IAutomationRegistryMaster2_3 as Registry, AutomationRegistryBase2_3} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol";
import {AutomationRegistrar2_3} from "../v2_3/AutomationRegistrar2_3.sol";
import {ChainModuleBase} from "../../chains/ChainModuleBase.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {MockUpkeep} from "../../mocks/MockUpkeep.sol";
import {IWrappedNative} from "../interfaces/v2_3/IWrappedNative.sol";
import {WETH9} from "./WETH9.sol";
@@ -40,7 +41,8 @@ contract BaseTest is Test {
// contracts
LinkToken internal linkToken;
- ERC20Mock internal usdToken;
+ ERC20Mock6Decimals internal usdToken6;
+ ERC20Mock internal usdToken18;
WETH9 internal weth;
MockV3Aggregator internal LINK_USD_FEED;
MockV3Aggregator internal NATIVE_USD_FEED;
@@ -73,7 +75,8 @@ contract BaseTest is Test {
vm.startPrank(OWNER);
linkToken = new LinkToken();
linkToken.grantMintRole(OWNER);
- usdToken = new ERC20Mock("MOCK_ERC20", "MOCK_ERC20", OWNER, 0);
+ usdToken18 = new ERC20Mock("MOCK_ERC20_18Decimals", "MOCK_ERC20_18Decimals", OWNER, 0);
+ usdToken6 = new ERC20Mock6Decimals("MOCK_ERC20_6Decimals", "MOCK_ERC20_6Decimals", OWNER, 0);
weth = new WETH9();
LINK_USD_FEED = new MockV3Aggregator(8, 2_000_000_000); // $20
@@ -114,14 +117,22 @@ contract BaseTest is Test {
vm.deal(UPKEEP_ADMIN, 100 ether);
vm.deal(FINANCE_ADMIN, 100 ether);
vm.deal(STRANGER, 100 ether);
+
linkToken.mint(OWNER, 1000e18);
linkToken.mint(UPKEEP_ADMIN, 1000e18);
linkToken.mint(FINANCE_ADMIN, 1000e18);
linkToken.mint(STRANGER, 1000e18);
- usdToken.mint(OWNER, 1000e18);
- usdToken.mint(UPKEEP_ADMIN, 1000e18);
- usdToken.mint(FINANCE_ADMIN, 1000e18);
- usdToken.mint(STRANGER, 1000e18);
+
+ usdToken18.mint(OWNER, 1000e18);
+ usdToken18.mint(UPKEEP_ADMIN, 1000e18);
+ usdToken18.mint(FINANCE_ADMIN, 1000e18);
+ usdToken18.mint(STRANGER, 1000e18);
+
+ usdToken6.mint(OWNER, 1000e6);
+ usdToken6.mint(UPKEEP_ADMIN, 1000e6);
+ usdToken6.mint(FINANCE_ADMIN, 1000e6);
+ usdToken6.mint(STRANGER, 1000e6);
+
weth.mint(OWNER, 1000e18);
weth.mint(UPKEEP_ADMIN, 1000e18);
weth.mint(FINANCE_ADMIN, 1000e18);
@@ -154,14 +165,16 @@ contract BaseTest is Test {
) internal returns (Registry, AutomationRegistrar2_3) {
Registry registry = deployRegistry(payoutMode);
- IERC20[] memory billingTokens = new IERC20[](3);
- billingTokens[0] = IERC20(address(usdToken));
+ IERC20[] memory billingTokens = new IERC20[](4);
+ billingTokens[0] = IERC20(address(usdToken18));
billingTokens[1] = IERC20(address(weth));
billingTokens[2] = IERC20(address(linkToken));
+ billingTokens[3] = IERC20(address(usdToken6));
uint256[] memory minRegistrationFees = new uint256[](billingTokens.length);
- minRegistrationFees[0] = 100000000000000000000; // 100 USD
- minRegistrationFees[1] = 5000000000000000000; // 5 Native
- minRegistrationFees[2] = 5000000000000000000; // 5 LINK
+ minRegistrationFees[0] = 100e18; // 100 USD
+ minRegistrationFees[1] = 5e18; // 5 Native
+ minRegistrationFees[2] = 5e18; // 5 LINK
+ minRegistrationFees[3] = 100e6; // 100 USD
address[] memory billingTokenAddresses = new address[](billingTokens.length);
for (uint256 i = 0; i < billingTokens.length; i++) {
billingTokenAddresses[i] = address(billingTokens[i]);
@@ -173,21 +186,32 @@ contract BaseTest is Test {
flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS, // 2 cents
priceFeed: address(USDTOKEN_USD_FEED),
fallbackPrice: 100_000_000, // $1
- minSpend: 1000000000000000000 // 1 USD
+ minSpend: 1e18, // 1 USD
+ decimals: 18
});
billingTokenConfigs[1] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: DEFAULT_GAS_FEE_PPB, // 15%
flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS, // 2 cents
priceFeed: address(NATIVE_USD_FEED),
fallbackPrice: 100_000_000, // $1
- minSpend: 5000000000000000000 // 5 Native
+ minSpend: 5e18, // 5 Native
+ decimals: 18
});
billingTokenConfigs[2] = AutomationRegistryBase2_3.BillingConfig({
gasFeePPB: DEFAULT_GAS_FEE_PPB, // 10%
flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS, // 2 cents
priceFeed: address(LINK_USD_FEED),
fallbackPrice: 1_000_000_000, // $10
- minSpend: 1000000000000000000 // 1 LINK
+ minSpend: 1e18, // 1 LINK
+ decimals: 18
+ });
+ billingTokenConfigs[3] = AutomationRegistryBase2_3.BillingConfig({
+ gasFeePPB: DEFAULT_GAS_FEE_PPB, // 15%
+ flatFeeMilliCents: DEFAULT_FLAT_FEE_MILLI_CENTS, // 2 cents
+ priceFeed: address(USDTOKEN_USD_FEED),
+ fallbackPrice: 1e8, // $1
+ minSpend: 1e6, // 1 USD
+ decimals: 6
});
if (payoutMode == AutoBase.PayoutMode.OFF_CHAIN) {
@@ -418,10 +442,10 @@ contract BaseTest is Test {
linkToken.mint(recipient, amount);
}
- /// @dev mints USDToken to the recipient
- function _mintERC20(address recipient, uint256 amount) internal {
+ /// @dev mints USDToken with 18 decimals to the recipient
+ function _mintERC20_18Decimals(address recipient, uint256 amount) internal {
vm.prank(OWNER);
- usdToken.mint(recipient, amount);
+ usdToken18.mint(recipient, amount);
}
/// @dev returns a pseudo-random 32 bytes
diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol
index ed0dd717998..ab9d7ae0b20 100644
--- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol
+++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol
@@ -6,9 +6,10 @@ import {IAutomationRegistryMaster2_3} from "../interfaces/v2_3/IAutomationRegist
import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol";
import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol";
import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IWrappedNative} from "../interfaces/v2_3/IWrappedNative.sol";
import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol";
+import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol";
/**
* @notice Contract to accept requests for upkeep registrations
@@ -21,6 +22,8 @@ import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/u
* they can just listen to `RegistrationRequested` & `RegistrationApproved` events and know the status on registrations.
*/
contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC677Receiver {
+ using SafeERC20 for IERC20;
+
/**
* DISABLED: No auto approvals, all new upkeeps should be approved manually.
* ENABLED_SENDER_ALLOWLIST: Auto approvals for allowed senders subject to max allowed. Manual for rest.
@@ -74,6 +77,7 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC
struct PendingRequest {
address admin;
uint96 balance;
+ IERC20 billingToken;
}
/**
* @member upkeepContract address to perform upkeep on
@@ -145,6 +149,7 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC
error InvalidBillingToken();
error InvalidDataLength();
error TransferFailed(address to);
+ error DuplicateEntry();
error OnlyAdminOrOwner();
error OnlyLink();
error RequestNotFound();
@@ -190,9 +195,7 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC
i_WRAPPED_NATIVE_TOKEN.deposit{value: msg.value}();
} else {
// send ERC20 payment, including wrapped native token
- if (!requestParams.billingToken.transferFrom(msg.sender, address(this), requestParams.amount)) {
- revert TransferFailed(address(this));
- }
+ requestParams.billingToken.safeTransferFrom(msg.sender, address(this), requestParams.amount);
}
return _register(requestParams, msg.sender);
@@ -217,11 +220,12 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC
}
/**
- * @notice cancel will remove a registration request and return the refunds to the request.admin
+ * @notice cancel will remove a registration request from the pending request queue and return the refunds to the request.admin
* @param hash the request hash
*/
function cancel(bytes32 hash) external {
PendingRequest memory request = s_pendingRequests[hash];
+
if (!(msg.sender == request.admin || msg.sender == owner())) {
revert OnlyAdminOrOwner();
}
@@ -229,10 +233,9 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC
revert RequestNotFound();
}
delete s_pendingRequests[hash];
- bool success = i_LINK.transfer(request.admin, request.balance);
- if (!success) {
- revert TransferFailed(request.admin);
- }
+
+ request.billingToken.safeTransfer(request.admin, request.balance);
+
emit RegistrationRejected(hash);
}
@@ -340,9 +343,8 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC
/**
* @dev verify registration request and emit RegistrationRequested event
- * @dev we currently allow multiple duplicate registrations by adding to the original registration's balance
- * we could make this much simpler by using a nonce to differentiate otherwise identical requests and then
- * we don't have to worry about identical registrations
+ * @dev we don't allow multiple duplicate registrations by adding to the original registration's balance
+ * users can cancel and re-register if they want to update the registration
*/
function _register(RegistrationParams memory params, address sender) private returns (uint256) {
if (params.amount < s_minRegistrationAmounts[params.billingToken]) {
@@ -356,6 +358,10 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC
}
bytes32 hash = keccak256(abi.encode(params));
+ if (s_pendingRequests[hash].admin != address(0)) {
+ revert DuplicateEntry();
+ }
+
emit RegistrationRequested(
hash,
params.name,
@@ -375,8 +381,11 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC
s_triggerRegistrations[params.triggerType].approvedCount++;
upkeepId = _approve(params, hash);
} else {
- uint96 newBalance = s_pendingRequests[hash].balance + params.amount;
- s_pendingRequests[hash] = PendingRequest({admin: params.adminAddress, balance: newBalance});
+ s_pendingRequests[hash] = PendingRequest({
+ admin: params.adminAddress,
+ balance: params.amount,
+ billingToken: params.billingToken
+ });
}
return upkeepId;
diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol
index 074d9c93327..c95c2138f71 100644
--- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol
+++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol
@@ -9,8 +9,7 @@ import {AutomationRegistryLogicC2_3} from "./AutomationRegistryLogicC2_3.sol";
import {Chainable} from "../../Chainable.sol";
import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol";
import {OCR2Abstract} from "../../../shared/ocr2/OCR2Abstract.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
-import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
/**
* @notice Registry for adding work for Chainlink nodes to perform on client
@@ -228,37 +227,6 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain
s_reserveAmounts[IERC20(address(i_link))] += transmitVars.totalReimbursement + transmitVars.totalPremium;
}
- /**
- * @notice adds fund to an upkeep
- * @param id the upkeepID
- * @param amount the amount of funds to add, in the upkeep's billing token
- */
- function addFunds(uint256 id, uint96 amount) external payable {
- Upkeep memory upkeep = s_upkeep[id];
- if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled();
-
- if (msg.value != 0) {
- if (upkeep.billingToken != IERC20(i_wrappedNativeToken)) {
- revert InvalidToken();
- }
- amount = SafeCast.toUint96(msg.value);
- }
-
- s_upkeep[id].balance = upkeep.balance + amount;
- s_reserveAmounts[upkeep.billingToken] = s_reserveAmounts[upkeep.billingToken] + amount;
-
- if (msg.value == 0) {
- // ERC20 payment
- bool success = upkeep.billingToken.transferFrom(msg.sender, address(this), amount);
- if (!success) revert TransferFailed();
- } else {
- // native payment
- i_wrappedNativeToken.deposit{value: amount}();
- }
-
- emit FundsAdded(id, msg.sender, amount);
- }
-
/**
* @notice uses LINK's transferAndCall to LINK and add funding to an upkeep
* @dev safe to cast uint256 to uint96 as total LINK supply is under UINT96MAX
diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol
index 087d907ab44..275b25b28d0 100644
--- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol
+++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol
@@ -11,7 +11,7 @@ import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Inte
import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol";
import {KeeperCompatibleInterface} from "../../interfaces/KeeperCompatibleInterface.sol";
import {IChainModule} from "../../interfaces/IChainModule.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol";
import {IWrappedNative} from "../interfaces/v2_3/IWrappedNative.sol";
@@ -58,8 +58,8 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
// tx itself, but since payment processing itself takes gas, and it needs the overhead as input, we use fixed constants
// to account for gas used in payment processing. These values are calibrated using hardhat tests which simulates various cases and verifies that
// the variables result in accurate estimation
- uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 51_000; // Fixed overhead per tx
- uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 9_000; // Overhead per upkeep performed in batch
+ uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 51_200; // Fixed overhead per tx
+ uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 9_200; // Overhead per upkeep performed in batch
LinkTokenInterface internal immutable i_link;
AggregatorV3Interface internal immutable i_linkUSDFeed;
@@ -375,6 +375,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
uint32 gasFeePPB;
uint24 flatFeeMilliCents; // min fee is $0.00001, max fee is $167
AggregatorV3Interface priceFeed;
+ uint8 decimals;
// 1st word, read in calculating BillingTokenPaymentParams
uint256 fallbackPrice;
// 2nd word only read if stale
@@ -395,6 +396,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
* @dev this is a memory-only struct, so struct packing is less important
*/
struct BillingTokenPaymentParams {
+ uint8 decimals;
uint32 gasFeePPB;
uint24 flatFeeMilliCents;
uint256 priceUSD;
@@ -426,8 +428,8 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
/**
* @notice struct containing receipt information about a payment or cost estimation
- * @member gasCharge the amount to charge a user for gas spent
- * @member premium the premium charged to the user, shared between all nodes
+ * @member gasCharge the amount to charge a user for gas spent using the billing token's native decimals
+ * @member premium the premium charged to the user, shared between all nodes, using the billing token's native decimals
* @member gasReimbursementJuels the amount to reimburse a node for gas spent
* @member premiumJuels the premium paid to NOPs, shared between all nodes
*/
@@ -633,6 +635,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
BillingConfig storage config = s_billingConfigs[billingToken];
paymentParams.flatFeeMilliCents = config.flatFeeMilliCents;
paymentParams.gasFeePPB = config.gasFeePPB;
+ paymentParams.decimals = config.decimals;
(, int256 feedValue, , uint256 timestamp, ) = config.priceFeed.latestRoundData();
if (
feedValue <= 0 ||
@@ -660,22 +663,38 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
HotVars memory hotVars,
PaymentParams memory paymentParams
) internal view returns (PaymentReceipt memory receipt) {
+ uint256 decimals = paymentParams.billingTokenParams.decimals;
uint256 gasWei = paymentParams.fastGasWei * hotVars.gasCeilingMultiplier;
// in case it's actual execution use actual gas price, capped by fastGasWei * gasCeilingMultiplier
if (paymentParams.isTransaction && tx.gasprice < gasWei) {
gasWei = tx.gasprice;
}
+ // scaling factor is based on decimals of billing token, and applies to premium and gasCharge
+ uint256 numeratorScalingFactor = decimals > 18 ? 10 ** (decimals - 18) : 1;
+ uint256 denominatorScalingFactor = decimals < 18 ? 10 ** (18 - decimals) : 1;
+
+ // gas calculation
uint256 gasPaymentHexaicosaUSD = (gasWei *
(paymentParams.gasLimit + paymentParams.gasOverhead) +
paymentParams.l1CostWei) * paymentParams.nativeUSD; // gasPaymentHexaicosaUSD has an extra 8 zeros because of decimals on nativeUSD feed
- receipt.gasCharge = SafeCast.toUint96(gasPaymentHexaicosaUSD / paymentParams.billingTokenParams.priceUSD); // has units of attoBillingToken, or "wei"
+ // gasCharge is scaled by the billing token's decimals
+ receipt.gasCharge = SafeCast.toUint96(
+ (gasPaymentHexaicosaUSD * numeratorScalingFactor) /
+ (paymentParams.billingTokenParams.priceUSD * denominatorScalingFactor)
+ );
receipt.gasReimbursementJuels = SafeCast.toUint96(gasPaymentHexaicosaUSD / paymentParams.linkUSD);
+
+ // premium calculation
uint256 flatFeeHexaicosaUSD = uint256(paymentParams.billingTokenParams.flatFeeMilliCents) * 1e21; // 1e13 for milliCents to attoUSD and 1e8 for attoUSD to hexaicosaUSD
uint256 premiumHexaicosaUSD = ((((gasWei * paymentParams.gasLimit) + paymentParams.l1CostWei) *
paymentParams.billingTokenParams.gasFeePPB *
paymentParams.nativeUSD) / 1e9) + flatFeeHexaicosaUSD;
- receipt.premium = SafeCast.toUint96(premiumHexaicosaUSD / paymentParams.billingTokenParams.priceUSD);
+ // premium is scaled by the billing token's decimals
+ receipt.premium = SafeCast.toUint96(
+ (premiumHexaicosaUSD * numeratorScalingFactor) /
+ (paymentParams.billingTokenParams.priceUSD * denominatorScalingFactor)
+ );
receipt.premiumJuels = SafeCast.toUint96(premiumHexaicosaUSD / paymentParams.linkUSD);
return receipt;
@@ -975,7 +994,9 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
PaymentReceipt memory receipt = _calculatePaymentAmount(hotVars, paymentParams);
+ // balance is in the token's native decimals
uint96 balance = upkeep.balance;
+ // payment is in the token's native decimals
uint96 payment = receipt.gasCharge + receipt.premium;
// this shouldn't happen, but in rare edge cases, we charge the full balance in case the user
@@ -1064,6 +1085,11 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
IERC20 token = billingTokens[i];
BillingConfig memory config = billingConfigs[i];
+ // most ERC20 tokens are 18 decimals, priceFeed must be 8 decimals
+ if (config.decimals != token.decimals() || config.priceFeed.decimals() != 8) {
+ revert InvalidToken();
+ }
+
// if LINK is a billing option, payout mode must be ON_CHAIN
if (address(token) == address(i_link) && mode == PayoutMode.OFF_CHAIN) {
revert InvalidToken();
diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol
index 22753cc4ac3..99fc97ce5ce 100644
--- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol
+++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol
@@ -11,7 +11,7 @@ import {AutomationForwarder} from "../../AutomationForwarder.sol";
import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol";
import {UpkeepTranscoderInterfaceV2} from "../../interfaces/UpkeepTranscoderInterfaceV2.sol";
import {MigratableKeeperRegistryInterfaceV2} from "../../interfaces/MigratableKeeperRegistryInterfaceV2.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol";
/**
@@ -154,6 +154,7 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
) revert MigrationNotPermitted();
if (s_storage.transcoder == ZERO_ADDRESS) revert TranscoderNotSet();
if (ids.length == 0) revert ArrayHasNoEntries();
+
IERC20 billingToken;
uint256 balanceToTransfer;
uint256 id;
@@ -163,12 +164,13 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
bytes[] memory checkDatas = new bytes[](ids.length);
bytes[] memory triggerConfigs = new bytes[](ids.length);
bytes[] memory offchainConfigs = new bytes[](ids.length);
+
for (uint256 idx = 0; idx < ids.length; idx++) {
id = ids[idx];
upkeep = s_upkeep[id];
if (idx == 0) {
- billingToken = s_upkeep[id].billingToken;
+ billingToken = upkeep.billingToken;
balanceToTransfer = upkeep.balance;
}
@@ -178,9 +180,13 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
billingToken.safeTransfer(destination, balanceToTransfer);
billingToken = upkeep.billingToken;
balanceToTransfer = upkeep.balance;
+ } else if (idx != 0) {
+ balanceToTransfer += upkeep.balance;
}
+
_requireAdminAndNotCancelled(id);
upkeep.forwarder.updateRegistry(destination);
+
upkeeps[idx] = upkeep;
admins[idx] = s_upkeepAdmin[id];
checkDatas[idx] = s_checkData[id];
@@ -194,13 +200,11 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
delete s_proposedAdmin[id];
s_upkeepIDs.remove(id);
emit UpkeepMigrated(id, upkeep.balance, destination);
-
- // always transfer the rolling sum at the end of the array
- if (idx == ids.length - 1) {
- s_reserveAmounts[billingToken] = s_reserveAmounts[billingToken] - balanceToTransfer;
- billingToken.safeTransfer(destination, balanceToTransfer);
- }
}
+ // always transfer the rolling sum in the end
+ s_reserveAmounts[billingToken] = s_reserveAmounts[billingToken] - balanceToTransfer;
+ billingToken.safeTransfer(destination, balanceToTransfer);
+
bytes memory encodedUpkeeps = abi.encode(
ids,
upkeeps,
diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol
index 5063bd48dd8..d69d5e0bd96 100644
--- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol
+++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol
@@ -6,8 +6,9 @@ import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contra
import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
import {AutomationRegistryLogicC2_3} from "./AutomationRegistryLogicC2_3.sol";
import {Chainable} from "../../Chainable.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol";
+import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol";
contract AutomationRegistryLogicB2_3 is AutomationRegistryBase2_3, Chainable {
using Address for address;
@@ -233,6 +234,36 @@ contract AutomationRegistryLogicB2_3 is AutomationRegistryBase2_3, Chainable {
// | UPKEEP MANAGEMENT |
// ================================================================
+ /**
+ * @notice adds fund to an upkeep
+ * @param id the upkeepID
+ * @param amount the amount of funds to add, in the upkeep's billing token
+ */
+ function addFunds(uint256 id, uint96 amount) external payable {
+ Upkeep memory upkeep = s_upkeep[id];
+ if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled();
+
+ if (msg.value != 0) {
+ if (upkeep.billingToken != IERC20(i_wrappedNativeToken)) {
+ revert InvalidToken();
+ }
+ amount = SafeCast.toUint96(msg.value);
+ }
+
+ s_upkeep[id].balance = upkeep.balance + amount;
+ s_reserveAmounts[upkeep.billingToken] = s_reserveAmounts[upkeep.billingToken] + amount;
+
+ if (msg.value == 0) {
+ // ERC20 payment
+ upkeep.billingToken.safeTransferFrom(msg.sender, address(this), amount);
+ } else {
+ // native payment
+ i_wrappedNativeToken.deposit{value: amount}();
+ }
+
+ emit FundsAdded(id, msg.sender, amount);
+ }
+
/**
* @notice overrides the billing config for an upkeep
* @param id the upkeepID
diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol
index ad8512bef33..0a429730bdb 100644
--- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol
+++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol
@@ -6,7 +6,7 @@ import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contra
import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol";
import {IChainModule} from "../../interfaces/IChainModule.sol";
-import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
+import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IAutomationV21PlusCommon} from "../../interfaces/IAutomationV21PlusCommon.sol";
contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 {
@@ -96,7 +96,8 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 {
}
/**
- * @notice sets the payees for the transmitters
+ * @notice this is used by the owner to set the initial payees for newly added transmitters. The owner is not allowed to change payees for existing transmitters.
+ * @dev the IGNORE_ADDRESS is a "helper" that makes it easier to construct a list of payees when you only care about setting the payee for a small number of transmitters.
*/
function setPayees(address[] calldata payees) external onlyOwner {
if (s_transmittersList.length != payees.length) revert ParameterLengthError();
@@ -104,9 +105,13 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 {
address transmitter = s_transmittersList[i];
address oldPayee = s_transmitterPayees[transmitter];
address newPayee = payees[i];
+
if (
(newPayee == ZERO_ADDRESS) || (oldPayee != ZERO_ADDRESS && oldPayee != newPayee && newPayee != IGNORE_ADDRESS)
- ) revert InvalidPayee();
+ ) {
+ revert InvalidPayee();
+ }
+
if (newPayee != IGNORE_ADDRESS) {
s_transmitterPayees[transmitter] = newPayee;
}
diff --git a/contracts/src/v0.8/automation/mocks/ERC20Mock6Decimals.sol b/contracts/src/v0.8/automation/mocks/ERC20Mock6Decimals.sol
new file mode 100644
index 00000000000..63a61814e0d
--- /dev/null
+++ b/contracts/src/v0.8/automation/mocks/ERC20Mock6Decimals.sol
@@ -0,0 +1,17 @@
+pragma solidity ^0.8.0;
+
+import {ERC20Mock} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/mocks/ERC20Mock.sol";
+
+// mock ERC20 with 6 decimals
+contract ERC20Mock6Decimals is ERC20Mock {
+ constructor(
+ string memory name,
+ string memory symbol,
+ address initialAccount,
+ uint256 initialBalance
+ ) payable ERC20Mock(name, symbol, initialAccount, initialBalance) {}
+
+ function decimals() public view virtual override returns (uint8) {
+ return 6;
+ }
+}
diff --git a/contracts/src/v0.8/keystone/KeystoneForwarder.sol b/contracts/src/v0.8/keystone/KeystoneForwarder.sol
index b4a9501e8f4..e6e2675fa2d 100644
--- a/contracts/src/v0.8/keystone/KeystoneForwarder.sol
+++ b/contracts/src/v0.8/keystone/KeystoneForwarder.sol
@@ -10,6 +10,14 @@ import {Utils} from "./libraries/Utils.sol";
contract KeystoneForwarder is IForwarder, ConfirmedOwner, TypeAndVersionInterface {
error ReentrantCall();
+ /// @notice This error is returned when the data with report is invalid.
+ /// This can happen if the data is shorter than SELECTOR_LENGTH + REPORT_LENGTH.
+ /// @param data the data that was received
+ error InvalidData(bytes data);
+
+ uint256 private constant SELECTOR_LENGTH = 4;
+ uint256 private constant REPORT_LENGTH = 64;
+
struct HotVars {
bool reentrancyGuard; // guard against reentrancy
}
@@ -26,7 +34,9 @@ contract KeystoneForwarder is IForwarder, ConfirmedOwner, TypeAndVersionInterfac
bytes calldata data,
bytes[] calldata signatures
) external nonReentrant returns (bool) {
- require(data.length > 4 + 64, "invalid data length");
+ if (data.length < SELECTOR_LENGTH + REPORT_LENGTH) {
+ revert InvalidData(data);
+ }
// data is an encoded call with the selector prefixed: (bytes4 selector, bytes report, ...)
// we are able to partially decode just the first param, since we don't know the rest
diff --git a/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol b/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol
index 5bff4b63221..83600b6c864 100644
--- a/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol
+++ b/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol
@@ -132,12 +132,12 @@ abstract contract VRFConsumerBaseV2Plus is IVRFMigratableConsumerV2Plus, Confirm
* @param randomWords the VRF output expanded to the requested number of words
*/
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
- function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual;
+ function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal virtual;
// rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
// proof. rawFulfillRandomness then calls fulfillRandomness, after validating
// the origin of the call
- function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external {
+ function rawFulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) external {
if (msg.sender != address(s_vrfCoordinator)) {
revert OnlyCoordinatorCanFulfill(msg.sender, address(s_vrfCoordinator));
}
diff --git a/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapper.sol b/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapper.sol
index 1b80cc8838a..4a806db5515 100644
--- a/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapper.sol
+++ b/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapper.sol
@@ -32,6 +32,26 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
LinkTokenInterface internal immutable i_link;
AggregatorV3Interface internal immutable i_link_native_feed;
+ event FulfillmentTxSizeSet(uint32 size);
+ event ConfigSet(
+ uint32 wrapperGasOverhead,
+ uint32 coordinatorGasOverhead,
+ uint16 coordinatorGasOverheadPerWord,
+ uint8 coordinatorNativePremiumPercentage,
+ uint8 coordinatorLinkPremiumPercentage,
+ bytes32 keyHash,
+ uint8 maxNumWords,
+ uint32 stalenessSeconds,
+ int256 fallbackWeiPerUnitLink,
+ uint32 fulfillmentFlatFeeNativePPM,
+ uint32 fulfillmentFlatFeeLinkDiscountPPM
+ );
+ event FallbackWeiPerUnitLinkUsed(uint256 requestId, int256 fallbackWeiPerUnitLink);
+ event Withdrawn(address indexed to, uint256 amount);
+ event NativeWithdrawn(address indexed to, uint256 amount);
+ event Enabled();
+ event Disabled();
+
error LinkAlreadySet();
error LinkDiscountTooHigh(uint32 flatFeeLinkDiscountPPM, uint32 flatFeeNativePPM);
error InvalidPremiumPercentage(uint8 premiumPercentage, uint8 max);
@@ -100,6 +120,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
// in the pricing for wrapped requests. This includes the gas costs of proof verification and
// payment calculation in the coordinator.
uint32 private s_coordinatorGasOverhead;
+ uint16 private s_coordinatorGasOverheadPerWord;
// s_fulfillmentFlatFeeLinkPPM is the flat fee in millionths of native that VRFCoordinatorV2
// charges for native payment.
@@ -119,7 +140,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
// Wrapper has no premium. This premium is for VRFCoordinator.
uint8 private s_coordinatorLinkPremiumPercentage;
- // 6 bytes left
+ // 4 bytes left
/* Storage Slot 5: END */
struct Callback {
@@ -202,6 +223,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
function setConfig(
uint32 _wrapperGasOverhead,
uint32 _coordinatorGasOverhead,
+ uint16 _coordinatorGasOverheadPerWord,
uint8 _coordinatorNativePremiumPercentage,
uint8 _coordinatorLinkPremiumPercentage,
bytes32 _keyHash,
@@ -223,6 +245,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
s_wrapperGasOverhead = _wrapperGasOverhead;
s_coordinatorGasOverhead = _coordinatorGasOverhead;
+ s_coordinatorGasOverheadPerWord = _coordinatorGasOverheadPerWord;
s_coordinatorNativePremiumPercentage = _coordinatorNativePremiumPercentage;
s_coordinatorLinkPremiumPercentage = _coordinatorLinkPremiumPercentage;
s_keyHash = _keyHash;
@@ -238,6 +261,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
emit ConfigSet(
_wrapperGasOverhead,
_coordinatorGasOverhead,
+ _coordinatorGasOverheadPerWord,
_coordinatorNativePremiumPercentage,
_coordinatorLinkPremiumPercentage,
_keyHash,
@@ -270,6 +294,9 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
* @return coordinatorGasOverhead reflects the gas overhead of the coordinator's
* fulfillRandomWords function.
*
+ * @return coordinatorGasOverheadPerWord reflects the gas overhead per word of the coordinator's
+ * fulfillRandomWords function.
+ *
* @return wrapperNativePremiumPercentage is the premium ratio in percentage for native payment. For example, a value of 0
* indicates no premium. A value of 15 indicates a 15 percent premium.
*
@@ -292,6 +319,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
uint32 fulfillmentFlatFeeLinkDiscountPPM,
uint32 wrapperGasOverhead,
uint32 coordinatorGasOverhead,
+ uint16 coordinatorGasOverheadPerWord,
uint8 wrapperNativePremiumPercentage,
uint8 wrapperLinkPremiumPercentage,
bytes32 keyHash,
@@ -305,6 +333,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
s_fulfillmentFlatFeeLinkDiscountPPM,
s_wrapperGasOverhead,
s_coordinatorGasOverhead,
+ s_coordinatorGasOverheadPerWord,
s_coordinatorNativePremiumPercentage,
s_coordinatorLinkPremiumPercentage,
s_keyHash,
@@ -322,16 +351,18 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
* @param _callbackGasLimit is the gas limit used to estimate the price.
*/
function calculateRequestPrice(
- uint32 _callbackGasLimit
+ uint32 _callbackGasLimit,
+ uint32 _numWords
) external view override onlyConfiguredNotDisabled returns (uint256) {
(int256 weiPerUnitLink, ) = _getFeedData();
- return _calculateRequestPrice(_callbackGasLimit, tx.gasprice, weiPerUnitLink);
+ return _calculateRequestPrice(_callbackGasLimit, _numWords, tx.gasprice, weiPerUnitLink);
}
function calculateRequestPriceNative(
- uint32 _callbackGasLimit
+ uint32 _callbackGasLimit,
+ uint32 _numWords
) external view override onlyConfiguredNotDisabled returns (uint256) {
- return _calculateRequestPriceNative(_callbackGasLimit, tx.gasprice);
+ return _calculateRequestPriceNative(_callbackGasLimit, _numWords, tx.gasprice);
}
/**
@@ -345,20 +376,26 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
*/
function estimateRequestPrice(
uint32 _callbackGasLimit,
+ uint32 _numWords,
uint256 _requestGasPriceWei
) external view override onlyConfiguredNotDisabled returns (uint256) {
(int256 weiPerUnitLink, ) = _getFeedData();
- return _calculateRequestPrice(_callbackGasLimit, _requestGasPriceWei, weiPerUnitLink);
+ return _calculateRequestPrice(_callbackGasLimit, _numWords, _requestGasPriceWei, weiPerUnitLink);
}
function estimateRequestPriceNative(
uint32 _callbackGasLimit,
+ uint32 _numWords,
uint256 _requestGasPriceWei
) external view override onlyConfiguredNotDisabled returns (uint256) {
- return _calculateRequestPriceNative(_callbackGasLimit, _requestGasPriceWei);
+ return _calculateRequestPriceNative(_callbackGasLimit, _numWords, _requestGasPriceWei);
}
- function _calculateRequestPriceNative(uint256 _gas, uint256 _requestGasPrice) internal view returns (uint256) {
+ function _calculateRequestPriceNative(
+ uint256 _gas,
+ uint32 _numWords,
+ uint256 _requestGasPrice
+ ) internal view returns (uint256) {
// costWei is the base fee denominated in wei (native)
// (wei/gas) * gas
uint256 wrapperCostWei = _requestGasPrice * s_wrapperGasOverhead;
@@ -366,7 +403,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
// coordinatorCostWei takes into account the L1 posting costs of the VRF fulfillment transaction, if we are on an L2.
// (wei/gas) * gas + l1wei
uint256 coordinatorCostWei = _requestGasPrice *
- (_gas + s_coordinatorGasOverhead) +
+ (_gas + _getCoordinatorGasOverhead(_numWords)) +
ChainSpecificUtil._getL1CalldataGasCost(s_fulfillmentTxSizeBytes);
// coordinatorCostWithPremiumAndFlatFeeWei is the coordinator cost with the percentage premium and flat fee applied
@@ -379,6 +416,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
function _calculateRequestPrice(
uint256 _gas,
+ uint32 _numWords,
uint256 _requestGasPrice,
int256 _weiPerUnitLink
) internal view returns (uint256) {
@@ -389,7 +427,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
// coordinatorCostWei takes into account the L1 posting costs of the VRF fulfillment transaction, if we are on an L2.
// (wei/gas) * gas + l1wei
uint256 coordinatorCostWei = _requestGasPrice *
- (_gas + s_coordinatorGasOverhead) +
+ (_gas + _getCoordinatorGasOverhead(_numWords)) +
ChainSpecificUtil._getL1CalldataGasCost(s_fulfillmentTxSizeBytes);
// coordinatorCostWithPremiumAndFlatFeeWei is the coordinator cost with the percentage premium and flat fee applied
@@ -427,7 +465,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
checkPaymentMode(extraArgs, true);
uint32 eip150Overhead = _getEIP150Overhead(callbackGasLimit);
(int256 weiPerUnitLink, bool isFeedStale) = _getFeedData();
- uint256 price = _calculateRequestPrice(callbackGasLimit, tx.gasprice, weiPerUnitLink);
+ uint256 price = _calculateRequestPrice(callbackGasLimit, numWords, tx.gasprice, weiPerUnitLink);
// solhint-disable-next-line gas-custom-errors
require(_amount >= price, "fee too low");
// solhint-disable-next-line gas-custom-errors
@@ -486,7 +524,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
checkPaymentMode(extraArgs, false);
uint32 eip150Overhead = _getEIP150Overhead(_callbackGasLimit);
- uint256 price = _calculateRequestPriceNative(_callbackGasLimit, tx.gasprice);
+ uint256 price = _calculateRequestPriceNative(_callbackGasLimit, _numWords, tx.gasprice);
// solhint-disable-next-line gas-custom-errors
require(msg.value >= price, "fee too low");
// solhint-disable-next-line gas-custom-errors
@@ -557,7 +595,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
}
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
- function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override {
+ function fulfillRandomWords(uint256 _requestId, uint256[] calldata _randomWords) internal override {
Callback memory callback = s_callbacks[_requestId];
delete s_callbacks[_requestId];
@@ -603,6 +641,10 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
return gas / 63 + 1;
}
+ function _getCoordinatorGasOverhead(uint32 numWords) internal view returns (uint32) {
+ return s_coordinatorGasOverhead + numWords * s_coordinatorGasOverheadPerWord;
+ }
+
/**
* @dev calls target address with exactly gasAmount gas and data as calldata
* or reverts if at least gasAmount gas is not available.
diff --git a/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol b/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol
index 07a3292facc..89a7dcbf064 100644
--- a/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol
+++ b/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol
@@ -63,7 +63,7 @@ abstract contract VRFV2PlusWrapperConsumerBase {
uint32 _numWords,
bytes memory extraArgs
) internal returns (uint256 requestId, uint256 reqPrice) {
- reqPrice = i_vrfV2PlusWrapper.calculateRequestPrice(_callbackGasLimit);
+ reqPrice = i_vrfV2PlusWrapper.calculateRequestPrice(_callbackGasLimit, _numWords);
i_linkToken.transferAndCall(
address(i_vrfV2PlusWrapper),
reqPrice,
@@ -79,7 +79,7 @@ abstract contract VRFV2PlusWrapperConsumerBase {
uint32 _numWords,
bytes memory extraArgs
) internal returns (uint256 requestId, uint256 requestPrice) {
- requestPrice = i_vrfV2PlusWrapper.calculateRequestPriceNative(_callbackGasLimit);
+ requestPrice = i_vrfV2PlusWrapper.calculateRequestPriceNative(_callbackGasLimit, _numWords);
return (
i_vrfV2PlusWrapper.requestRandomWordsInNative{value: requestPrice}(
_callbackGasLimit,
diff --git a/contracts/src/v0.8/vrf/dev/interfaces/IVRFV2PlusWrapper.sol b/contracts/src/v0.8/vrf/dev/interfaces/IVRFV2PlusWrapper.sol
index 93f6bf0ef11..85b0c47659d 100644
--- a/contracts/src/v0.8/vrf/dev/interfaces/IVRFV2PlusWrapper.sol
+++ b/contracts/src/v0.8/vrf/dev/interfaces/IVRFV2PlusWrapper.sol
@@ -2,25 +2,6 @@
pragma solidity ^0.8.0;
interface IVRFV2PlusWrapper {
- event FulfillmentTxSizeSet(uint32 size);
- event ConfigSet(
- uint32 wrapperGasOverhead,
- uint32 coordinatorGasOverhead,
- uint8 coordinatorNativePremiumPercentage,
- uint8 coordinatorLinkPremiumPercentage,
- bytes32 keyHash,
- uint8 maxNumWords,
- uint32 stalenessSeconds,
- int256 fallbackWeiPerUnitLink,
- uint32 fulfillmentFlatFeeNativePPM,
- uint32 fulfillmentFlatFeeLinkDiscountPPM
- );
- event FallbackWeiPerUnitLinkUsed(uint256 requestId, int256 fallbackWeiPerUnitLink);
- event Withdrawn(address indexed to, uint256 amount);
- event NativeWithdrawn(address indexed to, uint256 amount);
- event Enabled();
- event Disabled();
-
/**
* @return the request ID of the most recent VRF V2 request made by this wrapper. This should only
* be relied option within the same transaction that the request was made.
@@ -35,8 +16,9 @@ interface IVRFV2PlusWrapper {
* @dev simulation. To estimate the price at a specific gas price, use the estimatePrice function.
*
* @param _callbackGasLimit is the gas limit used to estimate the price.
+ * @param _numWords is the number of words to request.
*/
- function calculateRequestPrice(uint32 _callbackGasLimit) external view returns (uint256);
+ function calculateRequestPrice(uint32 _callbackGasLimit, uint32 _numWords) external view returns (uint256);
/**
* @notice Calculates the price of a VRF request in native with the given callbackGasLimit at the current
@@ -46,8 +28,9 @@ interface IVRFV2PlusWrapper {
* @dev simulation. To estimate the price at a specific gas price, use the estimatePrice function.
*
* @param _callbackGasLimit is the gas limit used to estimate the price.
+ * @param _numWords is the number of words to request.
*/
- function calculateRequestPriceNative(uint32 _callbackGasLimit) external view returns (uint256);
+ function calculateRequestPriceNative(uint32 _callbackGasLimit, uint32 _numWords) external view returns (uint256);
/**
* @notice Estimates the price of a VRF request with a specific gas limit and gas price.
@@ -56,9 +39,14 @@ interface IVRFV2PlusWrapper {
* @dev pricing.
*
* @param _callbackGasLimit is the gas limit used to estimate the price.
+ * @param _numWords is the number of words to request.
* @param _requestGasPriceWei is the gas price in wei used for the estimation.
*/
- function estimateRequestPrice(uint32 _callbackGasLimit, uint256 _requestGasPriceWei) external view returns (uint256);
+ function estimateRequestPrice(
+ uint32 _callbackGasLimit,
+ uint32 _numWords,
+ uint256 _requestGasPriceWei
+ ) external view returns (uint256);
/**
* @notice Estimates the price of a VRF request in native with a specific gas limit and gas price.
@@ -67,10 +55,12 @@ interface IVRFV2PlusWrapper {
* @dev pricing.
*
* @param _callbackGasLimit is the gas limit used to estimate the price.
+ * @param _numWords is the number of words to request.
* @param _requestGasPriceWei is the gas price in wei used for the estimation.
*/
function estimateRequestPriceNative(
uint32 _callbackGasLimit,
+ uint32 _numWords,
uint256 _requestGasPriceWei
) external view returns (uint256);
@@ -85,7 +75,7 @@ interface IVRFV2PlusWrapper {
uint32 _callbackGasLimit,
uint16 _requestConfirmations,
uint32 _numWords,
- bytes memory extraArgs
+ bytes calldata extraArgs
) external payable returns (uint256 requestId);
function link() external view returns (address);
diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol
index 6599a68a96e..c88d7dec397 100644
--- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol
+++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol
@@ -5,6 +5,7 @@ import {BlockhashStoreInterface} from "../../interfaces/BlockhashStoreInterface.
// solhint-disable-next-line no-unused-import
import {IVRFCoordinatorV2Plus, IVRFSubscriptionV2Plus} from "../interfaces/IVRFCoordinatorV2Plus.sol";
import {VRF} from "../../../vrf/VRF.sol";
+import {VRFTypes} from "../../VRFTypes.sol";
import {VRFConsumerBaseV2Plus, IVRFMigratableConsumerV2Plus} from "../VRFConsumerBaseV2Plus.sol";
import {ChainSpecificUtil} from "../../../ChainSpecificUtil.sol";
import {SubscriptionAPI} from "../SubscriptionAPI.sol";
@@ -30,37 +31,39 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
// 5k is plenty for an EXTCODESIZE call (2600) + warm CALL (100)
// and some arithmetic operations.
uint256 private constant GAS_FOR_CALL_EXACT_CHECK = 5_000;
+ // upper bound limit for premium percentages to make sure fee calculations don't overflow
+ uint8 private constant PREMIUM_PERCENTAGE_MAX = 155;
error InvalidRequestConfirmations(uint16 have, uint16 min, uint16 max);
error GasLimitTooBig(uint32 have, uint32 want);
error NumWordsTooBig(uint32 have, uint32 want);
+ error MsgDataTooBig(uint256 have, uint32 max);
error ProvingKeyAlreadyRegistered(bytes32 keyHash);
error NoSuchProvingKey(bytes32 keyHash);
error InvalidLinkWeiPrice(int256 linkWei);
+ error LinkDiscountTooHigh(uint32 flatFeeLinkDiscountPPM, uint32 flatFeeNativePPM);
+ error InvalidPremiumPercentage(uint8 premiumPercentage, uint8 max);
error NoCorrespondingRequest();
error IncorrectCommitment();
error BlockhashNotInStore(uint256 blockNum);
error PaymentTooLarge();
error InvalidExtraArgsTag();
+ error GasPriceExceeded(uint256 gasPrice, uint256 maxGas);
/// @notice emitted when version in the request doesn't match expected version
error InvalidVersion(uint8 requestVersion, uint8 expectedVersion);
/// @notice emitted when transferred balance (msg.value) does not match the metadata in V1MigrationData
error InvalidNativeBalance(uint256 transferredValue, uint96 expectedValue);
error SubscriptionIDCollisionFound();
- struct RequestCommitment {
- uint64 blockNum;
- uint256 subId;
- uint32 callbackGasLimit;
- uint32 numWords;
- address sender;
- bytes extraArgs;
+ struct ProvingKey {
+ bool exists; // proving key exists
+ uint64 maxGas; // gas lane max gas price for fulfilling requests
}
- mapping(bytes32 => bool) /* keyHash */ /* exists */ internal s_provingKeys;
+ mapping(bytes32 => ProvingKey) /* keyHash */ /* provingKey */ public s_provingKeys;
bytes32[] public s_provingKeyHashes;
mapping(uint256 => bytes32) /* requestID */ /* commitment */ public s_requestCommitments;
+ event ProvingKeyRegistered(bytes32 keyHash, uint64 maxGas);
- event ProvingKeyRegistered(bytes32 keyHash);
event RandomWordsRequested(
bytes32 indexed keyHash,
uint256 requestId,
@@ -72,26 +75,18 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
bytes extraArgs,
address indexed sender
);
+
event RandomWordsFulfilled(
uint256 indexed requestId,
uint256 outputSeed,
- uint256 indexed subID,
+ uint256 indexed subId,
uint96 payment,
- bool success
+ bool nativePayment,
+ bool success,
+ bool onlyPremium
);
- int256 internal s_fallbackWeiPerUnitLink;
-
- FeeConfig internal s_feeConfig;
-
- struct FeeConfig {
- // Flat fee charged per fulfillment in millionths of link
- // So fee range is [0, 2^32/10^6].
- uint32 fulfillmentFlatFeeLinkPPM;
- // Flat fee charged per fulfillment in millionths of native.
- // So fee range is [0, 2^32/10^6].
- uint32 fulfillmentFlatFeeNativePPM;
- }
+ int256 public s_fallbackWeiPerUnitLink;
event ConfigSet(
uint16 minimumRequestConfirmations,
@@ -99,26 +94,30 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
uint32 stalenessSeconds,
uint32 gasAfterPaymentCalculation,
int256 fallbackWeiPerUnitLink,
+ uint32 fulfillmentFlatFeeNativePPM,
+ uint32 fulfillmentFlatFeeLinkDiscountPPM,
uint8 nativePremiumPercentage,
uint8 linkPremiumPercentage
);
+ event FallbackWeiPerUnitLinkUsed(uint256 requestId, int256 fallbackWeiPerUnitLink);
+
constructor(address blockhashStore) SubscriptionAPI() {
BLOCKHASH_STORE = BlockhashStoreInterface(blockhashStore);
}
/**
- * @notice Registers a proving key to an oracle.
+ * @notice Registers a proving key to.
* @param publicProvingKey key that oracle can use to submit vrf fulfillments
*/
- function registerProvingKey(uint256[2] calldata publicProvingKey) external onlyOwner {
+ function registerProvingKey(uint256[2] calldata publicProvingKey, uint64 maxGas) external onlyOwner {
bytes32 kh = hashOfKey(publicProvingKey);
- if (s_provingKeys[kh]) {
+ if (s_provingKeys[kh].exists) {
revert ProvingKeyAlreadyRegistered(kh);
}
- s_provingKeys[kh] = true;
+ s_provingKeys[kh] = ProvingKey({exists: true, maxGas: maxGas});
s_provingKeyHashes.push(kh);
- emit ProvingKeyRegistered(kh);
+ emit ProvingKeyRegistered(kh, maxGas);
}
/**
@@ -136,6 +135,8 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
* @param stalenessSeconds if the native/link feed is more stale then this, use the fallback price
* @param gasAfterPaymentCalculation gas used in doing accounting after completing the gas measurement
* @param fallbackWeiPerUnitLink fallback native/link price in the case of a stale feed
+ * @param fulfillmentFlatFeeNativePPM flat fee in native for native payment
+ * @param fulfillmentFlatFeeLinkDiscountPPM flat fee discount for link payment in native
* @param nativePremiumPercentage native premium percentage
* @param linkPremiumPercentage link premium percentage
*/
@@ -160,6 +161,15 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
if (fallbackWeiPerUnitLink <= 0) {
revert InvalidLinkWeiPrice(fallbackWeiPerUnitLink);
}
+ if (fulfillmentFlatFeeLinkDiscountPPM > fulfillmentFlatFeeNativePPM) {
+ revert LinkDiscountTooHigh(fulfillmentFlatFeeLinkDiscountPPM, fulfillmentFlatFeeNativePPM);
+ }
+ if (nativePremiumPercentage > PREMIUM_PERCENTAGE_MAX) {
+ revert InvalidPremiumPercentage(nativePremiumPercentage, PREMIUM_PERCENTAGE_MAX);
+ }
+ if (linkPremiumPercentage > PREMIUM_PERCENTAGE_MAX) {
+ revert InvalidPremiumPercentage(linkPremiumPercentage, PREMIUM_PERCENTAGE_MAX);
+ }
s_config = Config({
minimumRequestConfirmations: minimumRequestConfirmations,
maxGasLimit: maxGasLimit,
@@ -178,6 +188,8 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
stalenessSeconds,
gasAfterPaymentCalculation,
fallbackWeiPerUnitLink,
+ fulfillmentFlatFeeNativePPM,
+ fulfillmentFlatFeeLinkDiscountPPM,
nativePremiumPercentage,
linkPremiumPercentage
);
@@ -232,18 +244,18 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
*/
function requestRandomWords(
VRFV2PlusClient.RandomWordsRequest calldata req
- ) external override nonReentrant returns (uint256) {
+ ) external override nonReentrant returns (uint256 requestId) {
// Input validation using the subscription storage.
- if (s_subscriptionConfigs[req.subId].owner == address(0)) {
+ uint256 subId = req.subId;
+ if (s_subscriptionConfigs[subId].owner == address(0)) {
revert InvalidSubscription();
}
// Its important to ensure that the consumer is in fact who they say they
// are, otherwise they could use someone else's subscription balance.
- // A nonce of 0 indicates consumer is not allocated to the sub.
mapping(uint256 => ConsumerConfig) storage consumerConfigs = s_consumers[msg.sender];
- ConsumerConfig memory consumerConfig = consumerConfigs[req.subId];
+ ConsumerConfig memory consumerConfig = consumerConfigs[subId];
if (!consumerConfig.active) {
- revert InvalidConsumer(req.subId, msg.sender);
+ revert InvalidConsumer(subId, msg.sender);
}
// Input validation using the config storage word.
if (
@@ -265,19 +277,21 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
if (req.numWords > MAX_NUM_WORDS) {
revert NumWordsTooBig(req.numWords, MAX_NUM_WORDS);
}
+
// Note we do not check whether the keyHash is valid to save gas.
// The consequence for users is that they can send requests
// for invalid keyHashes which will simply not be fulfilled.
++consumerConfig.nonce;
- (uint256 requestId, uint256 preSeed) = _computeRequestId(req.keyHash, msg.sender, req.subId, consumerConfig.nonce);
+ ++consumerConfig.pendingReqCount;
+ uint256 preSeed;
+ (requestId, preSeed) = _computeRequestId(req.keyHash, msg.sender, subId, consumerConfig.nonce);
- VRFV2PlusClient.ExtraArgsV1 memory extraArgs = _fromBytes(req.extraArgs);
- bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(extraArgs);
+ bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(_fromBytes(req.extraArgs));
s_requestCommitments[requestId] = keccak256(
abi.encode(
requestId,
ChainSpecificUtil._getBlockNumber(),
- req.subId,
+ subId,
req.callbackGasLimit,
req.numWords,
msg.sender,
@@ -288,14 +302,14 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
req.keyHash,
requestId,
preSeed,
- req.subId,
+ subId,
req.requestConfirmations,
req.callbackGasLimit,
req.numWords,
extraArgsBytes,
msg.sender
);
- s_consumers[msg.sender][req.subId] = consumerConfig;
+ consumerConfigs[subId] = consumerConfig;
return requestId;
}
@@ -344,18 +358,19 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
}
struct Output {
- bytes32 keyHash;
+ ProvingKey provingKey;
uint256 requestId;
uint256 randomness;
}
function _getRandomnessFromProof(
Proof memory proof,
- RequestCommitment memory rc
+ VRFTypes.RequestCommitmentV2Plus memory rc
) internal view returns (Output memory) {
bytes32 keyHash = hashOfKey(proof.pk);
+ ProvingKey memory key = s_provingKeys[keyHash];
// Only registered proving keys are permitted.
- if (!s_provingKeys[keyHash]) {
+ if (!key.exists) {
revert NoSuchProvingKey(keyHash);
}
uint256 requestId = uint256(keccak256(abi.encode(keyHash, proof.seed)));
@@ -381,179 +396,232 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
// The seed actually used by the VRF machinery, mixing in the blockhash
uint256 actualSeed = uint256(keccak256(abi.encodePacked(proof.seed, blockHash)));
uint256 randomness = VRF._randomValueFromVRFProof(proof, actualSeed); // Reverts on failure
- return Output(keyHash, requestId, randomness);
+ return Output(key, requestId, randomness);
+ }
+
+ function _getValidatedGasPrice(bool onlyPremium, uint64 gasLaneMaxGas) internal view returns (uint256 gasPrice) {
+ if (tx.gasprice > gasLaneMaxGas) {
+ if (onlyPremium) {
+ // if only the premium amount needs to be billed, then the premium is capped by the gas lane max
+ return uint256(gasLaneMaxGas);
+ } else {
+ // Ensure gas price does not exceed the gas lane max gas price
+ revert GasPriceExceeded(tx.gasprice, gasLaneMaxGas);
+ }
+ }
+ return tx.gasprice;
+ }
+
+ function _deliverRandomness(
+ uint256 requestId,
+ VRFTypes.RequestCommitmentV2Plus memory rc,
+ uint256[] memory randomWords
+ ) internal returns (bool success) {
+ VRFConsumerBaseV2Plus v;
+ bytes memory resp = abi.encodeWithSelector(v.rawFulfillRandomWords.selector, requestId, randomWords);
+ // Call with explicitly the amount of callback gas requested
+ // Important to not let them exhaust the gas budget and avoid oracle payment.
+ // Do not allow any non-view/non-pure coordinator functions to be called
+ // during the consumers callback code via reentrancyLock.
+ // Note that _callWithExactGas will revert if we do not have sufficient gas
+ // to give the callee their requested amount.
+ s_config.reentrancyLock = true;
+ success = _callWithExactGas(rc.callbackGasLimit, rc.sender, resp);
+ s_config.reentrancyLock = false;
+ return success;
}
/*
- * @notice Fulfill a randomness request
+ * @notice Fulfill a randomness request.
* @param proof contains the proof and randomness
* @param rc request commitment pre-image, committed to at request time
+ * @param onlyPremium only charge premium
* @return payment amount billed to the subscription
* @dev simulated offchain to determine if sufficient balance is present to fulfill the request
*/
function fulfillRandomWords(
Proof memory proof,
- RequestCommitment memory rc,
- bool
- ) external nonReentrant returns (uint96) {
+ VRFTypes.RequestCommitmentV2Plus memory rc,
+ bool onlyPremium
+ ) external nonReentrant returns (uint96 payment) {
uint256 startGas = gasleft();
+ // fulfillRandomWords msg.data has 772 bytes and with an additional
+ // buffer of 32 bytes, we get 804 bytes.
+ /* Data size split:
+ * fulfillRandomWords function signature - 4 bytes
+ * proof - 416 bytes
+ * pk - 64 bytes
+ * gamma - 64 bytes
+ * c - 32 bytes
+ * s - 32 bytes
+ * seed - 32 bytes
+ * uWitness - 32 bytes
+ * cGammaWitness - 64 bytes
+ * sHashWitness - 64 bytes
+ * zInv - 32 bytes
+ * requestCommitment - 320 bytes
+ * blockNum - 32 bytes
+ * subId - 32 bytes
+ * callbackGasLimit - 32 bytes
+ * numWords - 32 bytes
+ * sender - 32 bytes
+ * extraArgs - 128 bytes
+ * onlyPremium - 32 bytes
+ */
+ if (msg.data.length > 804) {
+ revert MsgDataTooBig(msg.data.length, 804);
+ }
Output memory output = _getRandomnessFromProof(proof, rc);
+ uint256 gasPrice = _getValidatedGasPrice(onlyPremium, output.provingKey.maxGas);
- uint256[] memory randomWords = new uint256[](rc.numWords);
- for (uint256 i = 0; i < rc.numWords; i++) {
- randomWords[i] = uint256(keccak256(abi.encode(output.randomness, i)));
+ uint256[] memory randomWords;
+ uint256 randomness = output.randomness;
+ // stack too deep error
+ {
+ uint256 numWords = rc.numWords;
+ randomWords = new uint256[](numWords);
+ for (uint256 i = 0; i < numWords; ++i) {
+ randomWords[i] = uint256(keccak256(abi.encode(randomness, i)));
+ }
}
delete s_requestCommitments[output.requestId];
- VRFConsumerBaseV2Plus v;
- bytes memory resp = abi.encodeWithSelector(v.rawFulfillRandomWords.selector, output.requestId, randomWords);
- // Call with explicitly the amount of callback gas requested
- // Important to not let them exhaust the gas budget and avoid oracle payment.
- // Do not allow any non-view/non-pure coordinator functions to be called
- // during the consumers callback code via reentrancyLock.
- // Note that _callWithExactGas will revert if we do not have sufficient gas
- // to give the callee their requested amount.
- s_config.reentrancyLock = true;
- bool success = _callWithExactGas(rc.callbackGasLimit, rc.sender, resp);
- s_config.reentrancyLock = false;
+ bool success = _deliverRandomness(output.requestId, rc, randomWords);
// Increment the req count for the subscription.
- uint64 reqCount = s_subscriptions[rc.subId].reqCount;
- s_subscriptions[rc.subId].reqCount = reqCount + 1;
+ ++s_subscriptions[rc.subId].reqCount;
+ // Decrement the pending req count for the consumer.
+ --s_consumers[rc.sender][rc.subId].pendingReqCount;
+
+ bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1;
// stack too deep error
{
- bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1;
- // We want to charge users exactly for how much gas they use in their callback.
- // The gasAfterPaymentCalculation is meant to cover these additional operations where we
- // decrement the subscription balance and increment the oracles withdrawable balance.
- uint96 payment = _calculatePaymentAmount(
- startGas,
- s_config.gasAfterPaymentCalculation,
- tx.gasprice,
- nativePayment
- );
- if (nativePayment) {
- if (s_subscriptions[rc.subId].nativeBalance < payment) {
- revert InsufficientBalance();
- }
- s_subscriptions[rc.subId].nativeBalance -= payment;
- s_withdrawableNative += payment;
- } else {
- if (s_subscriptions[rc.subId].balance < payment) {
- revert InsufficientBalance();
- }
- s_subscriptions[rc.subId].balance -= payment;
- s_withdrawableTokens += payment;
+ // We want to charge users exactly for how much gas they use in their callback with
+ // an additional premium. If onlyPremium is true, only premium is charged without
+ // the gas cost. The gasAfterPaymentCalculation is meant to cover these additional
+ // operations where we decrement the subscription balance and increment the
+ // withdrawable balance.
+ bool isFeedStale;
+ (payment, isFeedStale) = _calculatePaymentAmount(startGas, gasPrice, nativePayment, onlyPremium);
+ if (isFeedStale) {
+ emit FallbackWeiPerUnitLinkUsed(output.requestId, s_fallbackWeiPerUnitLink);
}
+ }
+
+ _chargePayment(payment, nativePayment, rc.subId);
- // Include payment in the event for tracking costs.
- // event RandomWordsFulfilled(uint256 indexed requestId, uint256 outputSeed, uint96 payment, bytes extraArgs, bool success);
- emit RandomWordsFulfilled(output.requestId, output.randomness, rc.subId, payment, success);
+ // Include payment in the event for tracking costs.
+ emit RandomWordsFulfilled(output.requestId, randomness, rc.subId, payment, nativePayment, success, onlyPremium);
+
+ return payment;
+ }
- return payment;
+ function _chargePayment(uint96 payment, bool nativePayment, uint256 subId) internal {
+ Subscription storage subcription = s_subscriptions[subId];
+ if (nativePayment) {
+ uint96 prevBal = subcription.nativeBalance;
+ if (prevBal < payment) {
+ revert InsufficientBalance();
+ }
+ subcription.nativeBalance = prevBal - payment;
+ s_withdrawableNative += payment;
+ } else {
+ uint96 prevBal = subcription.balance;
+ if (prevBal < payment) {
+ revert InsufficientBalance();
+ }
+ subcription.balance = prevBal - payment;
+ s_withdrawableTokens += payment;
}
}
function _calculatePaymentAmount(
uint256 startGas,
- uint256 gasAfterPaymentCalculation,
uint256 weiPerUnitGas,
- bool nativePayment
- ) internal view returns (uint96) {
+ bool nativePayment,
+ bool onlyPremium
+ ) internal view returns (uint96, bool) {
if (nativePayment) {
- return
- _calculatePaymentAmountNative(
- startGas,
- gasAfterPaymentCalculation,
- s_feeConfig.fulfillmentFlatFeeNativePPM,
- weiPerUnitGas
- );
- }
- return
- _calculatePaymentAmountLink(
- startGas,
- gasAfterPaymentCalculation,
- s_feeConfig.fulfillmentFlatFeeLinkPPM,
- weiPerUnitGas
- );
+ return (_calculatePaymentAmountNative(startGas, weiPerUnitGas, onlyPremium), false);
+ }
+ return _calculatePaymentAmountLink(startGas, weiPerUnitGas, onlyPremium);
}
function _calculatePaymentAmountNative(
uint256 startGas,
- uint256 gasAfterPaymentCalculation,
- uint32 fulfillmentFlatFeePPM,
- uint256 weiPerUnitGas
+ uint256 weiPerUnitGas,
+ bool onlyPremium
) internal view returns (uint96) {
// Will return non-zero on chains that have this enabled
uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data);
// calculate the payment without the premium
- uint256 baseFeeWei = weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft());
- // calculate the flat fee in wei
- uint256 flatFeeWei = 1e12 * uint256(fulfillmentFlatFeePPM);
- // return the final fee with the flat fee and l1 cost (if applicable) added
- return uint96(baseFeeWei + flatFeeWei + l1CostWei);
+ uint256 baseFeeWei = weiPerUnitGas * (s_config.gasAfterPaymentCalculation + startGas - gasleft());
+ // calculate flat fee in native
+ uint256 flatFeeWei = 1e12 * uint256(s_config.fulfillmentFlatFeeNativePPM);
+ if (onlyPremium) {
+ return uint96((((l1CostWei + baseFeeWei) * (s_config.nativePremiumPercentage)) / 100) + flatFeeWei);
+ } else {
+ return uint96((((l1CostWei + baseFeeWei) * (100 + s_config.nativePremiumPercentage)) / 100) + flatFeeWei);
+ }
}
// Get the amount of gas used for fulfillment
function _calculatePaymentAmountLink(
uint256 startGas,
- uint256 gasAfterPaymentCalculation,
- uint32 fulfillmentFlatFeeLinkPPM,
- uint256 weiPerUnitGas
- ) internal view returns (uint96) {
- int256 weiPerUnitLink;
- weiPerUnitLink = _getFeedData();
+ uint256 weiPerUnitGas,
+ bool onlyPremium
+ ) internal view returns (uint96, bool) {
+ (int256 weiPerUnitLink, bool isFeedStale) = _getFeedData();
if (weiPerUnitLink <= 0) {
revert InvalidLinkWeiPrice(weiPerUnitLink);
}
// Will return non-zero on chains that have this enabled
uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data);
// (1e18 juels/link) ((wei/gas * gas) + l1wei) / (wei/link) = juels
- uint256 paymentNoFee = (1e18 * (weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft()) + l1CostWei)) /
+ uint256 paymentNoFee = (1e18 *
+ (weiPerUnitGas * (s_config.gasAfterPaymentCalculation + startGas - gasleft()) + l1CostWei)) /
uint256(weiPerUnitLink);
- uint256 fee = 1e12 * uint256(fulfillmentFlatFeeLinkPPM);
- if (paymentNoFee > (1e27 - fee)) {
+ // calculate the flat fee in wei
+ uint256 flatFeeWei = 1e12 *
+ uint256(s_config.fulfillmentFlatFeeNativePPM - s_config.fulfillmentFlatFeeLinkDiscountPPM);
+ uint256 flatFeeJuels = (1e18 * flatFeeWei) / uint256(weiPerUnitLink);
+ uint256 payment;
+ if (onlyPremium) {
+ payment = ((paymentNoFee * (s_config.linkPremiumPercentage)) / 100 + flatFeeJuels);
+ } else {
+ payment = ((paymentNoFee * (100 + s_config.linkPremiumPercentage)) / 100 + flatFeeJuels);
+ }
+ if (payment > 1e27) {
revert PaymentTooLarge(); // Payment + fee cannot be more than all of the link in existence.
}
- return uint96(paymentNoFee + fee);
+ return (uint96(payment), isFeedStale);
}
- function _getFeedData() private view returns (int256) {
+ function _getFeedData() private view returns (int256 weiPerUnitLink, bool isFeedStale) {
uint32 stalenessSeconds = s_config.stalenessSeconds;
- bool staleFallback = stalenessSeconds > 0;
uint256 timestamp;
- int256 weiPerUnitLink;
(, weiPerUnitLink, , timestamp, ) = LINK_NATIVE_FEED.latestRoundData();
// solhint-disable-next-line not-rely-on-time
- if (staleFallback && stalenessSeconds < block.timestamp - timestamp) {
+ isFeedStale = stalenessSeconds > 0 && stalenessSeconds < block.timestamp - timestamp;
+ if (isFeedStale) {
weiPerUnitLink = s_fallbackWeiPerUnitLink;
}
- return weiPerUnitLink;
+ return (weiPerUnitLink, isFeedStale);
}
- /*
- * @notice Check to see if there exists a request commitment consumers
- * for all consumers and keyhashes for a given sub.
- * @param subId - ID of the subscription
- * @return true if there exists at least one unfulfilled request for the subscription, false
- * otherwise.
- * @dev Looping is bounded to MAX_CONSUMERS*(number of keyhashes).
- * @dev Used to disable subscription canceling while outstanding request are present.
+ /**
+ * @inheritdoc IVRFSubscriptionV2Plus
*/
function pendingRequestExists(uint256 subId) public view override returns (bool) {
- SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId];
- for (uint256 i = 0; i < subConfig.consumers.length; i++) {
- for (uint256 j = 0; j < s_provingKeyHashes.length; j++) {
- (uint256 reqId, ) = _computeRequestId(
- s_provingKeyHashes[j],
- subConfig.consumers[i],
- subId,
- s_consumers[subConfig.consumers[i]][subId].nonce
- );
- if (s_requestCommitments[reqId] != 0) {
- return true;
- }
+ address[] storage consumers = s_subscriptionConfigs[subId].consumers;
+ uint256 consumersLength = consumers.length;
+ if (consumersLength == 0) {
+ return false;
+ }
+ for (uint256 i = 0; i < consumersLength; ++i) {
+ if (s_consumers[consumers[i]][subId].pendingReqCount > 0) {
+ return true;
}
}
return false;
@@ -572,7 +640,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
// Note bounded by MAX_CONSUMERS
address[] memory consumers = s_subscriptionConfigs[subId].consumers;
uint256 lastConsumerIndex = consumers.length - 1;
- for (uint256 i = 0; i < consumers.length; i++) {
+ for (uint256 i = 0; i < consumers.length; ++i) {
if (consumers[i] == consumer) {
address last = consumers[lastConsumerIndex];
// Storage write to preserve last element
@@ -582,7 +650,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
break;
}
}
- delete s_consumers[consumer][subId];
+ s_consumers[consumer][subId].active = false;
emit SubscriptionConsumerRemoved(subId, consumer);
}
@@ -627,7 +695,8 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
}
function _isTargetRegistered(address target) internal view returns (bool) {
- for (uint256 i = 0; i < s_migrationTargets.length; i++) {
+ uint256 migrationTargetsLength = s_migrationTargets.length;
+ for (uint256 i = 0; i < migrationTargetsLength; ++i) {
if (s_migrationTargets[i] == target) {
return true;
}
@@ -647,16 +716,16 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
if (!_isTargetRegistered(newCoordinator)) {
revert CoordinatorNotRegistered(newCoordinator);
}
- (uint96 balance, uint96 nativeBalance, , address owner, address[] memory consumers) = getSubscription(subId);
+ (uint96 balance, uint96 nativeBalance, , address subOwner, address[] memory consumers) = getSubscription(subId);
// solhint-disable-next-line gas-custom-errors
- require(owner == msg.sender, "Not subscription owner");
+ require(subOwner == msg.sender, "Not subscription owner");
// solhint-disable-next-line gas-custom-errors
require(!pendingRequestExists(subId), "Pending request exists");
V1MigrationData memory migrationData = V1MigrationData({
- fromVersion: migrationVersion(),
+ fromVersion: 1,
subId: subId,
- subOwner: owner,
+ subOwner: subOwner,
consumers: consumers,
linkBalance: balance,
nativeBalance: nativeBalance
@@ -674,7 +743,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is
// despite the fact that we follow best practices this is still probably safest
// to prevent any re-entrancy possibilities.
s_config.reentrancyLock = true;
- for (uint256 i = 0; i < consumers.length; i++) {
+ for (uint256 i = 0; i < consumers.length; ++i) {
IVRFMigratableConsumerV2Plus(consumers[i]).setCoordinator(newCoordinator);
}
s_config.reentrancyLock = false;
diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFMaliciousConsumerV2Plus.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFMaliciousConsumerV2Plus.sol
index cfc12102afd..f638b9744ea 100644
--- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFMaliciousConsumerV2Plus.sol
+++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFMaliciousConsumerV2Plus.sol
@@ -19,7 +19,7 @@ contract VRFMaliciousConsumerV2Plus is VRFConsumerBaseV2Plus {
}
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
- function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
+ function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
s_gasAvailable = gasleft();
s_randomWords = randomWords;
s_requestId = requestId;
diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusConsumerExample.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusConsumerExample.sol
index 8063d2ea1ce..d142f505f22 100644
--- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusConsumerExample.sol
+++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusConsumerExample.sol
@@ -66,7 +66,7 @@ contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus {
}
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
- function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
+ function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
// solhint-disable-next-line gas-custom-errors
require(requestId == s_recentRequestId, "request ID is incorrect");
s_requests[requestId].randomWords = randomWords;
diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusExternalSubOwnerExample.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusExternalSubOwnerExample.sol
index 6b5c9f4bf23..8eb22618c96 100644
--- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusExternalSubOwnerExample.sol
+++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusExternalSubOwnerExample.sol
@@ -20,7 +20,7 @@ contract VRFV2PlusExternalSubOwnerExample is VRFConsumerBaseV2Plus {
}
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
- function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
+ function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
// solhint-disable-next-line gas-custom-errors
require(requestId == s_requestId, "request ID is incorrect");
s_randomWords = randomWords;
diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol
index 85cb7727366..20fbf86da51 100644
--- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol
+++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol
@@ -37,7 +37,7 @@ contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus {
constructor(address _vrfCoordinator) VRFConsumerBaseV2Plus(_vrfCoordinator) {}
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
- function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override {
+ function fulfillRandomWords(uint256 _requestId, uint256[] calldata _randomWords) internal override {
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
s_requests[_requestId].fulfilmentTimestamp = block.timestamp;
diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusRevertingExample.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusRevertingExample.sol
index 07f2e44de0b..e52369b5c70 100644
--- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusRevertingExample.sol
+++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusRevertingExample.sol
@@ -19,7 +19,7 @@ contract VRFV2PlusRevertingExample is VRFConsumerBaseV2Plus {
}
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
- function fulfillRandomWords(uint256, uint256[] memory) internal pure override {
+ function fulfillRandomWords(uint256, uint256[] calldata) internal pure override {
// solhint-disable-next-line gas-custom-errors, reason-string
revert();
}
diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusSingleConsumerExample.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusSingleConsumerExample.sol
index b956ab0081a..4d8b6de4a43 100644
--- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusSingleConsumerExample.sol
+++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusSingleConsumerExample.sol
@@ -47,7 +47,7 @@ contract VRFV2PlusSingleConsumerExample is VRFConsumerBaseV2Plus {
}
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
- function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
+ function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
// solhint-disable-next-line gas-custom-errors
require(requestId == s_requestId, "request ID is incorrect");
s_randomWords = randomWords;
diff --git a/contracts/src/v0.8/vrf/test/VRFV2PlusWrapper.t.sol b/contracts/src/v0.8/vrf/test/VRFV2PlusWrapper.t.sol
index 89232f07dac..66bef8a1bcd 100644
--- a/contracts/src/v0.8/vrf/test/VRFV2PlusWrapper.t.sol
+++ b/contracts/src/v0.8/vrf/test/VRFV2PlusWrapper.t.sol
@@ -15,8 +15,8 @@ import {VRFV2PlusClient} from "../dev/libraries/VRFV2PlusClient.sol";
contract VRFV2PlusWrapperTest is BaseTest {
address internal constant LINK_WHALE = 0xD883a6A1C22fC4AbFE938a5aDF9B2Cc31b1BF18B;
bytes32 private vrfKeyHash = hex"9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528";
- uint32 private wrapperGasOverhead = 10_000;
- uint32 private coordinatorGasOverhead = 20_000;
+ uint32 private wrapperGasOverhead = 100_000;
+ uint32 private coordinatorGasOverhead = 200_000;
uint256 private s_wrapperSubscriptionId;
ExposedVRFCoordinatorV2_5 private s_testCoordinator;
@@ -75,19 +75,20 @@ contract VRFV2PlusWrapperTest is BaseTest {
1, // stalenessSeconds
50_000, // gasAfterPaymentCalculation
50000000000000000, // fallbackWeiPerUnitLink
- 500_000, // fulfillmentFlatFeeNativePPM
- 100_000, // fulfillmentFlatFeeLinkDiscountPPM
- 15, // nativePremiumPercentage
- 10 // linkPremiumPercentage
+ 0, // fulfillmentFlatFeeNativePPM
+ 0, // fulfillmentFlatFeeLinkDiscountPPM
+ 0, // nativePremiumPercentage
+ 0 // linkPremiumPercentage
);
}
function setConfigWrapper() internal {
vm.expectEmit(false, false, false, true, address(s_wrapper));
- emit ConfigSet(wrapperGasOverhead, coordinatorGasOverhead, 0, 0, vrfKeyHash, 10, 1, 50000000000000000, 0, 0);
+ emit ConfigSet(wrapperGasOverhead, coordinatorGasOverhead, 0, 0, 0, vrfKeyHash, 10, 1, 50000000000000000, 0, 0);
s_wrapper.setConfig(
wrapperGasOverhead, // wrapper gas overhead
coordinatorGasOverhead, // coordinator gas overhead
+ 0, // coordinator gas overhead per word
0, // native premium percentage,
0, // link premium percentage
vrfKeyHash, // keyHash
@@ -104,6 +105,7 @@ contract VRFV2PlusWrapperTest is BaseTest {
,
uint32 _wrapperGasOverhead,
uint32 _coordinatorGasOverhead,
+ uint16 _coordinatorGasOverheadPerWord,
uint8 _coordinatorNativePremiumPercentage,
uint8 _coordinatorLinkPremiumPercentage,
bytes32 _keyHash,
@@ -111,6 +113,7 @@ contract VRFV2PlusWrapperTest is BaseTest {
) = s_wrapper.getConfig();
assertEq(_wrapperGasOverhead, wrapperGasOverhead);
assertEq(_coordinatorGasOverhead, coordinatorGasOverhead);
+ assertEq(0, _coordinatorGasOverheadPerWord);
assertEq(0, _coordinatorNativePremiumPercentage);
assertEq(0, _coordinatorLinkPremiumPercentage);
assertEq(vrfKeyHash, _keyHash);
@@ -135,6 +138,7 @@ contract VRFV2PlusWrapperTest is BaseTest {
event ConfigSet(
uint32 wrapperGasOverhead,
uint32 coordinatorGasOverhead,
+ uint16 coordinatorGasOverheadPerWord,
uint8 coordinatorNativePremiumPercentage,
uint8 coordinatorLinkPremiumPercentage,
bytes32 keyHash,
@@ -208,7 +212,7 @@ contract VRFV2PlusWrapperTest is BaseTest {
emit Disabled();
s_wrapper.disable();
vm.expectRevert("wrapper is disabled");
- s_consumer.makeRequestNative(500_000, 0, 1);
+ s_consumer.makeRequestNative(100_000, 0, 0);
vm.expectEmit(false, false, false, true, address(s_wrapper));
emit Enabled();
s_wrapper.enable();
@@ -238,8 +242,8 @@ contract VRFV2PlusWrapperTest is BaseTest {
(uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId);
uint32 expectedPaid = callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead;
- uint256 wrapperNativeCostEstimate = s_wrapper.estimateRequestPriceNative(callbackGasLimit, tx.gasprice);
- uint256 wrapperCostCalculation = s_wrapper.calculateRequestPriceNative(callbackGasLimit);
+ uint256 wrapperNativeCostEstimate = s_wrapper.estimateRequestPriceNative(callbackGasLimit, 0, tx.gasprice);
+ uint256 wrapperCostCalculation = s_wrapper.calculateRequestPriceNative(callbackGasLimit, 0);
assertEq(paid, expectedPaid);
assertEq(uint256(paid), wrapperNativeCostEstimate);
assertEq(wrapperNativeCostEstimate, wrapperCostCalculation);
@@ -274,6 +278,7 @@ contract VRFV2PlusWrapperTest is BaseTest {
s_wrapper.setConfig(
wrapperGasOverhead, // wrapper gas overhead
coordinatorGasOverhead, // coordinator gas overhead
+ 0, // coordinator gas overhead per word
0, // native premium percentage,
0, // link premium percentage
vrfKeyHash, // keyHash
@@ -290,6 +295,7 @@ contract VRFV2PlusWrapperTest is BaseTest {
s_wrapper.setConfig(
wrapperGasOverhead, // wrapper gas overhead
coordinatorGasOverhead, // coordinator gas overhead
+ 0, // coordinator gas overhead per word
0, // native premium percentage,
0, // link premium percentage
vrfKeyHash, // keyHash
@@ -309,6 +315,7 @@ contract VRFV2PlusWrapperTest is BaseTest {
s_wrapper.setConfig(
wrapperGasOverhead, // wrapper gas overhead
coordinatorGasOverhead, // coordinator gas overhead
+ 0, // coordinator gas overhead per word
156, // native premium percentage,
0, // link premium percentage
vrfKeyHash, // keyHash
@@ -328,6 +335,7 @@ contract VRFV2PlusWrapperTest is BaseTest {
s_wrapper.setConfig(
wrapperGasOverhead, // wrapper gas overhead
coordinatorGasOverhead, // coordinator gas overhead
+ 0, // coordinator gas overhead per word
15, // native premium percentage,
202, // link premium percentage
vrfKeyHash, // keyHash
@@ -370,8 +378,8 @@ contract VRFV2PlusWrapperTest is BaseTest {
// Assert that the request was made correctly.
(uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId);
uint32 expectedPaid = (callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead) * 2;
- uint256 wrapperCostEstimate = s_wrapper.estimateRequestPrice(callbackGasLimit, tx.gasprice);
- uint256 wrapperCostCalculation = s_wrapper.calculateRequestPrice(callbackGasLimit);
+ uint256 wrapperCostEstimate = s_wrapper.estimateRequestPrice(callbackGasLimit, 0, tx.gasprice);
+ uint256 wrapperCostCalculation = s_wrapper.calculateRequestPrice(callbackGasLimit, 0);
assertEq(paid, expectedPaid); // 1_030_000 * 2 for link/native ratio
assertEq(uint256(paid), wrapperCostEstimate);
assertEq(wrapperCostEstimate, wrapperCostCalculation);
diff --git a/contracts/src/v0.8/vrf/test/VRFV2PlusWrapper_Migration.t.sol b/contracts/src/v0.8/vrf/test/VRFV2PlusWrapper_Migration.t.sol
index deaef4ba84e..7011bb6016b 100644
--- a/contracts/src/v0.8/vrf/test/VRFV2PlusWrapper_Migration.t.sol
+++ b/contracts/src/v0.8/vrf/test/VRFV2PlusWrapper_Migration.t.sol
@@ -102,6 +102,7 @@ contract VRFV2PlusWrapper_MigrationTest is BaseTest {
s_wrapper.setConfig(
wrapperGasOverhead, // wrapper gas overhead
coordinatorGasOverhead, // coordinator gas overhead
+ 0, // coordinator gas overhead per word
0, // native premium percentage,
0, // link premium percentage
vrfKeyHash, // keyHash
@@ -118,6 +119,7 @@ contract VRFV2PlusWrapper_MigrationTest is BaseTest {
,
uint32 _wrapperGasOverhead,
uint32 _coordinatorGasOverhead,
+ uint16 _coordinatorGasOverheadPerWord,
uint8 _coordinatorNativePremiumPercentage,
uint8 _coordinatorLinkPremiumPercentage,
bytes32 _keyHash,
@@ -125,6 +127,7 @@ contract VRFV2PlusWrapper_MigrationTest is BaseTest {
) = s_wrapper.getConfig();
assertEq(_wrapperGasOverhead, wrapperGasOverhead);
assertEq(_coordinatorGasOverhead, coordinatorGasOverhead);
+ assertEq(0, _coordinatorGasOverheadPerWord);
assertEq(0, _coordinatorNativePremiumPercentage);
assertEq(0, _coordinatorLinkPremiumPercentage);
assertEq(vrfKeyHash, _keyHash);
@@ -219,7 +222,7 @@ contract VRFV2PlusWrapper_MigrationTest is BaseTest {
// Request randomness from wrapper.
uint32 callbackGasLimit = 1_000_000;
- uint256 wrapperCost = s_wrapper.calculateRequestPrice(callbackGasLimit);
+ uint256 wrapperCost = s_wrapper.calculateRequestPrice(callbackGasLimit, 0);
vm.expectEmit(true, true, true, true);
emit WrapperRequestMade(1, wrapperCost);
uint256 requestId = s_consumer.makeRequest(callbackGasLimit, 0, 1);
@@ -227,8 +230,8 @@ contract VRFV2PlusWrapper_MigrationTest is BaseTest {
(uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId);
uint32 expectedPaid = (callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead) * 2;
- uint256 wrapperCostEstimate = s_wrapper.estimateRequestPrice(callbackGasLimit, tx.gasprice);
- uint256 wrapperCostCalculation = s_wrapper.calculateRequestPrice(callbackGasLimit);
+ uint256 wrapperCostEstimate = s_wrapper.estimateRequestPrice(callbackGasLimit, 0, tx.gasprice);
+ uint256 wrapperCostCalculation = s_wrapper.calculateRequestPrice(callbackGasLimit, 0);
assertEq(paid, expectedPaid); // 1_030_000 * 2 for link/native ratio
assertEq(uint256(paid), wrapperCostEstimate);
assertEq(wrapperCostEstimate, wrapperCostCalculation);
@@ -333,16 +336,17 @@ contract VRFV2PlusWrapper_MigrationTest is BaseTest {
// Request randomness from wrapper.
uint32 callbackGasLimit = 1_000_000;
+ uint32 numWords = 1;
vm.expectEmit(true, true, true, true);
- uint256 wrapperCost = s_wrapper.calculateRequestPriceNative(callbackGasLimit);
+ uint256 wrapperCost = s_wrapper.calculateRequestPriceNative(callbackGasLimit, numWords);
emit WrapperRequestMade(1, wrapperCost);
- uint256 requestId = s_consumer.makeRequestNative(callbackGasLimit, 0, 1);
+ uint256 requestId = s_consumer.makeRequestNative(callbackGasLimit, 0, numWords);
assertEq(requestId, 1);
(uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId);
uint32 expectedPaid = callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead;
- uint256 wrapperNativeCostEstimate = s_wrapper.estimateRequestPriceNative(callbackGasLimit, tx.gasprice);
- uint256 wrapperCostCalculation = s_wrapper.calculateRequestPriceNative(callbackGasLimit);
+ uint256 wrapperNativeCostEstimate = s_wrapper.estimateRequestPriceNative(callbackGasLimit, 0, tx.gasprice);
+ uint256 wrapperCostCalculation = s_wrapper.calculateRequestPriceNative(callbackGasLimit, 0);
assertEq(paid, expectedPaid);
assertEq(uint256(paid), wrapperNativeCostEstimate);
assertEq(wrapperNativeCostEstimate, wrapperCostCalculation);
diff --git a/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts b/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts
index 564d4e22a2c..02191dab999 100644
--- a/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts
+++ b/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts
@@ -232,6 +232,7 @@ describe('AutomationRegistrar2_3', () => {
priceFeed: await registry.getLinkUSDFeedAddress(),
fallbackPrice: 200,
minSpend: minimumRegistrationAmount,
+ decimals: 18,
},
],
)
@@ -1012,10 +1013,6 @@ describe('AutomationRegistrar2_3', () => {
.transferAndCall(registrar.address, amount, abiEncodedBytes)
const receipt = await tx.wait()
hash = receipt.logs[2].topics[1]
- // submit duplicate request (increase balance)
- await linkToken
- .connect(requestSender)
- .transferAndCall(registrar.address, amount, abiEncodedBytes)
})
it('reverts if not called by the admin / owner', async () => {
@@ -1036,7 +1033,7 @@ describe('AutomationRegistrar2_3', () => {
const before = await linkToken.balanceOf(await admin.getAddress())
const tx = await registrar.connect(registrarOwner).cancel(hash)
const after = await linkToken.balanceOf(await admin.getAddress())
- assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(2))))
+ assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(1))))
await expect(tx).to.emit(registrar, 'RegistrationRejected')
})
@@ -1044,7 +1041,7 @@ describe('AutomationRegistrar2_3', () => {
const before = await linkToken.balanceOf(await admin.getAddress())
const tx = await registrar.connect(admin).cancel(hash)
const after = await linkToken.balanceOf(await admin.getAddress())
- assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(2))))
+ assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(1))))
await expect(tx).to.emit(registrar, 'RegistrationRejected')
})
diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts
index 1036ab2ce88..e7480dd869a 100644
--- a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts
+++ b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts
@@ -667,6 +667,7 @@ describe('AutomationRegistry2_3', () => {
priceFeed: linkUSDFeed.address,
fallbackPrice: fallbackLinkPrice,
minSpend: minUpkeepSpend,
+ decimals: 18,
},
],
)
@@ -957,6 +958,7 @@ describe('AutomationRegistry2_3', () => {
priceFeed: linkUSDFeed.address,
fallbackPrice: fallbackLinkPrice,
minSpend: minUpkeepSpend,
+ decimals: 18,
},
],
]
@@ -976,6 +978,7 @@ describe('AutomationRegistry2_3', () => {
priceFeed: linkUSDFeed.address,
fallbackPrice: fallbackLinkPrice,
minSpend: minUpkeepSpend,
+ decimals: 18,
},
],
]
@@ -995,6 +998,7 @@ describe('AutomationRegistry2_3', () => {
priceFeed: linkUSDFeed.address,
fallbackPrice: fallbackLinkPrice,
minSpend: minUpkeepSpend,
+ decimals: 18,
},
],
]
@@ -4743,6 +4747,7 @@ describe('AutomationRegistry2_3', () => {
priceFeed: linkUSDFeed.address,
fallbackPrice: fallbackLinkPrice,
minSpend: newMinUpkeepSpend,
+ decimals: 18,
},
],
)
@@ -5258,6 +5263,7 @@ describe('AutomationRegistry2_3', () => {
priceFeed: linkUSDFeed.address,
fallbackPrice: fallbackLinkPrice,
minSpend: newMinUpkeepSpend,
+ decimals: 18,
},
],
)
@@ -5324,6 +5330,7 @@ describe('AutomationRegistry2_3', () => {
priceFeed: linkUSDFeed.address,
fallbackPrice: fallbackLinkPrice,
minSpend: newMinUpkeepSpend,
+ decimals: 18,
},
],
)
@@ -5385,6 +5392,7 @@ describe('AutomationRegistry2_3', () => {
priceFeed: linkUSDFeed.address,
fallbackPrice: fallbackLinkPrice,
minSpend: newMinUpkeepSpend,
+ decimals: 18,
},
],
)
diff --git a/core/README.md b/core/README.md
index 53adc2fb03f..5d767bc9140 100644
--- a/core/README.md
+++ b/core/README.md
@@ -6,8 +6,8 @@
-[![Go Report Card](https://goreportcard.com/badge/github.com/smartcontractkit/chainlink)](https://goreportcard.com/report/github.com/smartcontractkit/chainlink)
-[![GoDoc](https://godoc.org/github.com/smartcontractkit/chainlink?status.svg)](https://godoc.org/github.com/smartcontractkit/chainlink)
+[![Go Report Card](https://goreportcard.com/badge/github.com/smartcontractkit/chainlink/v2)](https://goreportcard.com/report/github.com/smartcontractkit/chainlink/v2)
+[![Go Reference](https://pkg.go.dev/badge/github.com/smartcontractkit/chainlink/v2.svg)](https://pkg.go.dev/github.com/smartcontractkit/chainlink/v2)
Chainlink Core is the API backend that Chainlink client contracts on Ethereum
make requests to. The backend utilizes Solidity contract ABIs to generate types
diff --git a/core/bridges/mocks/orm.go b/core/bridges/mocks/orm.go
index 2c92a7e8024..836f667bbeb 100644
--- a/core/bridges/mocks/orm.go
+++ b/core/bridges/mocks/orm.go
@@ -6,8 +6,12 @@ import (
auth "github.com/smartcontractkit/chainlink/v2/core/auth"
bridges "github.com/smartcontractkit/chainlink/v2/core/bridges"
+ context "context"
+
mock "github.com/stretchr/testify/mock"
+ sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
+
time "time"
)
@@ -16,9 +20,9 @@ type ORM struct {
mock.Mock
}
-// BridgeTypes provides a mock function with given fields: offset, limit
-func (_m *ORM) BridgeTypes(offset int, limit int) ([]bridges.BridgeType, int, error) {
- ret := _m.Called(offset, limit)
+// BridgeTypes provides a mock function with given fields: ctx, offset, limit
+func (_m *ORM) BridgeTypes(ctx context.Context, offset int, limit int) ([]bridges.BridgeType, int, error) {
+ ret := _m.Called(ctx, offset, limit)
if len(ret) == 0 {
panic("no return value specified for BridgeTypes")
@@ -27,25 +31,25 @@ func (_m *ORM) BridgeTypes(offset int, limit int) ([]bridges.BridgeType, int, er
var r0 []bridges.BridgeType
var r1 int
var r2 error
- if rf, ok := ret.Get(0).(func(int, int) ([]bridges.BridgeType, int, error)); ok {
- return rf(offset, limit)
+ if rf, ok := ret.Get(0).(func(context.Context, int, int) ([]bridges.BridgeType, int, error)); ok {
+ return rf(ctx, offset, limit)
}
- if rf, ok := ret.Get(0).(func(int, int) []bridges.BridgeType); ok {
- r0 = rf(offset, limit)
+ if rf, ok := ret.Get(0).(func(context.Context, int, int) []bridges.BridgeType); ok {
+ r0 = rf(ctx, offset, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]bridges.BridgeType)
}
}
- if rf, ok := ret.Get(1).(func(int, int) int); ok {
- r1 = rf(offset, limit)
+ if rf, ok := ret.Get(1).(func(context.Context, int, int) int); ok {
+ r1 = rf(ctx, offset, limit)
} else {
r1 = ret.Get(1).(int)
}
- if rf, ok := ret.Get(2).(func(int, int) error); ok {
- r2 = rf(offset, limit)
+ if rf, ok := ret.Get(2).(func(context.Context, int, int) error); ok {
+ r2 = rf(ctx, offset, limit)
} else {
r2 = ret.Error(2)
}
@@ -53,17 +57,17 @@ func (_m *ORM) BridgeTypes(offset int, limit int) ([]bridges.BridgeType, int, er
return r0, r1, r2
}
-// CreateBridgeType provides a mock function with given fields: bt
-func (_m *ORM) CreateBridgeType(bt *bridges.BridgeType) error {
- ret := _m.Called(bt)
+// CreateBridgeType provides a mock function with given fields: ctx, bt
+func (_m *ORM) CreateBridgeType(ctx context.Context, bt *bridges.BridgeType) error {
+ ret := _m.Called(ctx, bt)
if len(ret) == 0 {
panic("no return value specified for CreateBridgeType")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*bridges.BridgeType) error); ok {
- r0 = rf(bt)
+ if rf, ok := ret.Get(0).(func(context.Context, *bridges.BridgeType) error); ok {
+ r0 = rf(ctx, bt)
} else {
r0 = ret.Error(0)
}
@@ -71,17 +75,17 @@ func (_m *ORM) CreateBridgeType(bt *bridges.BridgeType) error {
return r0
}
-// CreateExternalInitiator provides a mock function with given fields: externalInitiator
-func (_m *ORM) CreateExternalInitiator(externalInitiator *bridges.ExternalInitiator) error {
- ret := _m.Called(externalInitiator)
+// CreateExternalInitiator provides a mock function with given fields: ctx, externalInitiator
+func (_m *ORM) CreateExternalInitiator(ctx context.Context, externalInitiator *bridges.ExternalInitiator) error {
+ ret := _m.Called(ctx, externalInitiator)
if len(ret) == 0 {
panic("no return value specified for CreateExternalInitiator")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*bridges.ExternalInitiator) error); ok {
- r0 = rf(externalInitiator)
+ if rf, ok := ret.Get(0).(func(context.Context, *bridges.ExternalInitiator) error); ok {
+ r0 = rf(ctx, externalInitiator)
} else {
r0 = ret.Error(0)
}
@@ -89,17 +93,17 @@ func (_m *ORM) CreateExternalInitiator(externalInitiator *bridges.ExternalInitia
return r0
}
-// DeleteBridgeType provides a mock function with given fields: bt
-func (_m *ORM) DeleteBridgeType(bt *bridges.BridgeType) error {
- ret := _m.Called(bt)
+// DeleteBridgeType provides a mock function with given fields: ctx, bt
+func (_m *ORM) DeleteBridgeType(ctx context.Context, bt *bridges.BridgeType) error {
+ ret := _m.Called(ctx, bt)
if len(ret) == 0 {
panic("no return value specified for DeleteBridgeType")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*bridges.BridgeType) error); ok {
- r0 = rf(bt)
+ if rf, ok := ret.Get(0).(func(context.Context, *bridges.BridgeType) error); ok {
+ r0 = rf(ctx, bt)
} else {
r0 = ret.Error(0)
}
@@ -107,17 +111,17 @@ func (_m *ORM) DeleteBridgeType(bt *bridges.BridgeType) error {
return r0
}
-// DeleteExternalInitiator provides a mock function with given fields: name
-func (_m *ORM) DeleteExternalInitiator(name string) error {
- ret := _m.Called(name)
+// DeleteExternalInitiator provides a mock function with given fields: ctx, name
+func (_m *ORM) DeleteExternalInitiator(ctx context.Context, name string) error {
+ ret := _m.Called(ctx, name)
if len(ret) == 0 {
panic("no return value specified for DeleteExternalInitiator")
}
var r0 error
- if rf, ok := ret.Get(0).(func(string) error); ok {
- r0 = rf(name)
+ if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
+ r0 = rf(ctx, name)
} else {
r0 = ret.Error(0)
}
@@ -125,9 +129,9 @@ func (_m *ORM) DeleteExternalInitiator(name string) error {
return r0
}
-// ExternalInitiators provides a mock function with given fields: offset, limit
-func (_m *ORM) ExternalInitiators(offset int, limit int) ([]bridges.ExternalInitiator, int, error) {
- ret := _m.Called(offset, limit)
+// ExternalInitiators provides a mock function with given fields: ctx, offset, limit
+func (_m *ORM) ExternalInitiators(ctx context.Context, offset int, limit int) ([]bridges.ExternalInitiator, int, error) {
+ ret := _m.Called(ctx, offset, limit)
if len(ret) == 0 {
panic("no return value specified for ExternalInitiators")
@@ -136,25 +140,25 @@ func (_m *ORM) ExternalInitiators(offset int, limit int) ([]bridges.ExternalInit
var r0 []bridges.ExternalInitiator
var r1 int
var r2 error
- if rf, ok := ret.Get(0).(func(int, int) ([]bridges.ExternalInitiator, int, error)); ok {
- return rf(offset, limit)
+ if rf, ok := ret.Get(0).(func(context.Context, int, int) ([]bridges.ExternalInitiator, int, error)); ok {
+ return rf(ctx, offset, limit)
}
- if rf, ok := ret.Get(0).(func(int, int) []bridges.ExternalInitiator); ok {
- r0 = rf(offset, limit)
+ if rf, ok := ret.Get(0).(func(context.Context, int, int) []bridges.ExternalInitiator); ok {
+ r0 = rf(ctx, offset, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]bridges.ExternalInitiator)
}
}
- if rf, ok := ret.Get(1).(func(int, int) int); ok {
- r1 = rf(offset, limit)
+ if rf, ok := ret.Get(1).(func(context.Context, int, int) int); ok {
+ r1 = rf(ctx, offset, limit)
} else {
r1 = ret.Get(1).(int)
}
- if rf, ok := ret.Get(2).(func(int, int) error); ok {
- r2 = rf(offset, limit)
+ if rf, ok := ret.Get(2).(func(context.Context, int, int) error); ok {
+ r2 = rf(ctx, offset, limit)
} else {
r2 = ret.Error(2)
}
@@ -162,9 +166,9 @@ func (_m *ORM) ExternalInitiators(offset int, limit int) ([]bridges.ExternalInit
return r0, r1, r2
}
-// FindBridge provides a mock function with given fields: name
-func (_m *ORM) FindBridge(name bridges.BridgeName) (bridges.BridgeType, error) {
- ret := _m.Called(name)
+// FindBridge provides a mock function with given fields: ctx, name
+func (_m *ORM) FindBridge(ctx context.Context, name bridges.BridgeName) (bridges.BridgeType, error) {
+ ret := _m.Called(ctx, name)
if len(ret) == 0 {
panic("no return value specified for FindBridge")
@@ -172,17 +176,17 @@ func (_m *ORM) FindBridge(name bridges.BridgeName) (bridges.BridgeType, error) {
var r0 bridges.BridgeType
var r1 error
- if rf, ok := ret.Get(0).(func(bridges.BridgeName) (bridges.BridgeType, error)); ok {
- return rf(name)
+ if rf, ok := ret.Get(0).(func(context.Context, bridges.BridgeName) (bridges.BridgeType, error)); ok {
+ return rf(ctx, name)
}
- if rf, ok := ret.Get(0).(func(bridges.BridgeName) bridges.BridgeType); ok {
- r0 = rf(name)
+ if rf, ok := ret.Get(0).(func(context.Context, bridges.BridgeName) bridges.BridgeType); ok {
+ r0 = rf(ctx, name)
} else {
r0 = ret.Get(0).(bridges.BridgeType)
}
- if rf, ok := ret.Get(1).(func(bridges.BridgeName) error); ok {
- r1 = rf(name)
+ if rf, ok := ret.Get(1).(func(context.Context, bridges.BridgeName) error); ok {
+ r1 = rf(ctx, name)
} else {
r1 = ret.Error(1)
}
@@ -190,9 +194,9 @@ func (_m *ORM) FindBridge(name bridges.BridgeName) (bridges.BridgeType, error) {
return r0, r1
}
-// FindBridges provides a mock function with given fields: name
-func (_m *ORM) FindBridges(name []bridges.BridgeName) ([]bridges.BridgeType, error) {
- ret := _m.Called(name)
+// FindBridges provides a mock function with given fields: ctx, name
+func (_m *ORM) FindBridges(ctx context.Context, name []bridges.BridgeName) ([]bridges.BridgeType, error) {
+ ret := _m.Called(ctx, name)
if len(ret) == 0 {
panic("no return value specified for FindBridges")
@@ -200,19 +204,19 @@ func (_m *ORM) FindBridges(name []bridges.BridgeName) ([]bridges.BridgeType, err
var r0 []bridges.BridgeType
var r1 error
- if rf, ok := ret.Get(0).(func([]bridges.BridgeName) ([]bridges.BridgeType, error)); ok {
- return rf(name)
+ if rf, ok := ret.Get(0).(func(context.Context, []bridges.BridgeName) ([]bridges.BridgeType, error)); ok {
+ return rf(ctx, name)
}
- if rf, ok := ret.Get(0).(func([]bridges.BridgeName) []bridges.BridgeType); ok {
- r0 = rf(name)
+ if rf, ok := ret.Get(0).(func(context.Context, []bridges.BridgeName) []bridges.BridgeType); ok {
+ r0 = rf(ctx, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]bridges.BridgeType)
}
}
- if rf, ok := ret.Get(1).(func([]bridges.BridgeName) error); ok {
- r1 = rf(name)
+ if rf, ok := ret.Get(1).(func(context.Context, []bridges.BridgeName) error); ok {
+ r1 = rf(ctx, name)
} else {
r1 = ret.Error(1)
}
@@ -220,9 +224,9 @@ func (_m *ORM) FindBridges(name []bridges.BridgeName) ([]bridges.BridgeType, err
return r0, r1
}
-// FindExternalInitiator provides a mock function with given fields: eia
-func (_m *ORM) FindExternalInitiator(eia *auth.Token) (*bridges.ExternalInitiator, error) {
- ret := _m.Called(eia)
+// FindExternalInitiator provides a mock function with given fields: ctx, eia
+func (_m *ORM) FindExternalInitiator(ctx context.Context, eia *auth.Token) (*bridges.ExternalInitiator, error) {
+ ret := _m.Called(ctx, eia)
if len(ret) == 0 {
panic("no return value specified for FindExternalInitiator")
@@ -230,19 +234,19 @@ func (_m *ORM) FindExternalInitiator(eia *auth.Token) (*bridges.ExternalInitiato
var r0 *bridges.ExternalInitiator
var r1 error
- if rf, ok := ret.Get(0).(func(*auth.Token) (*bridges.ExternalInitiator, error)); ok {
- return rf(eia)
+ if rf, ok := ret.Get(0).(func(context.Context, *auth.Token) (*bridges.ExternalInitiator, error)); ok {
+ return rf(ctx, eia)
}
- if rf, ok := ret.Get(0).(func(*auth.Token) *bridges.ExternalInitiator); ok {
- r0 = rf(eia)
+ if rf, ok := ret.Get(0).(func(context.Context, *auth.Token) *bridges.ExternalInitiator); ok {
+ r0 = rf(ctx, eia)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*bridges.ExternalInitiator)
}
}
- if rf, ok := ret.Get(1).(func(*auth.Token) error); ok {
- r1 = rf(eia)
+ if rf, ok := ret.Get(1).(func(context.Context, *auth.Token) error); ok {
+ r1 = rf(ctx, eia)
} else {
r1 = ret.Error(1)
}
@@ -250,9 +254,9 @@ func (_m *ORM) FindExternalInitiator(eia *auth.Token) (*bridges.ExternalInitiato
return r0, r1
}
-// FindExternalInitiatorByName provides a mock function with given fields: iname
-func (_m *ORM) FindExternalInitiatorByName(iname string) (bridges.ExternalInitiator, error) {
- ret := _m.Called(iname)
+// FindExternalInitiatorByName provides a mock function with given fields: ctx, iname
+func (_m *ORM) FindExternalInitiatorByName(ctx context.Context, iname string) (bridges.ExternalInitiator, error) {
+ ret := _m.Called(ctx, iname)
if len(ret) == 0 {
panic("no return value specified for FindExternalInitiatorByName")
@@ -260,17 +264,17 @@ func (_m *ORM) FindExternalInitiatorByName(iname string) (bridges.ExternalInitia
var r0 bridges.ExternalInitiator
var r1 error
- if rf, ok := ret.Get(0).(func(string) (bridges.ExternalInitiator, error)); ok {
- return rf(iname)
+ if rf, ok := ret.Get(0).(func(context.Context, string) (bridges.ExternalInitiator, error)); ok {
+ return rf(ctx, iname)
}
- if rf, ok := ret.Get(0).(func(string) bridges.ExternalInitiator); ok {
- r0 = rf(iname)
+ if rf, ok := ret.Get(0).(func(context.Context, string) bridges.ExternalInitiator); ok {
+ r0 = rf(ctx, iname)
} else {
r0 = ret.Get(0).(bridges.ExternalInitiator)
}
- if rf, ok := ret.Get(1).(func(string) error); ok {
- r1 = rf(iname)
+ if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+ r1 = rf(ctx, iname)
} else {
r1 = ret.Error(1)
}
@@ -278,9 +282,9 @@ func (_m *ORM) FindExternalInitiatorByName(iname string) (bridges.ExternalInitia
return r0, r1
}
-// GetCachedResponse provides a mock function with given fields: dotId, specId, maxElapsed
-func (_m *ORM) GetCachedResponse(dotId string, specId int32, maxElapsed time.Duration) ([]byte, error) {
- ret := _m.Called(dotId, specId, maxElapsed)
+// GetCachedResponse provides a mock function with given fields: ctx, dotId, specId, maxElapsed
+func (_m *ORM) GetCachedResponse(ctx context.Context, dotId string, specId int32, maxElapsed time.Duration) ([]byte, error) {
+ ret := _m.Called(ctx, dotId, specId, maxElapsed)
if len(ret) == 0 {
panic("no return value specified for GetCachedResponse")
@@ -288,19 +292,19 @@ func (_m *ORM) GetCachedResponse(dotId string, specId int32, maxElapsed time.Dur
var r0 []byte
var r1 error
- if rf, ok := ret.Get(0).(func(string, int32, time.Duration) ([]byte, error)); ok {
- return rf(dotId, specId, maxElapsed)
+ if rf, ok := ret.Get(0).(func(context.Context, string, int32, time.Duration) ([]byte, error)); ok {
+ return rf(ctx, dotId, specId, maxElapsed)
}
- if rf, ok := ret.Get(0).(func(string, int32, time.Duration) []byte); ok {
- r0 = rf(dotId, specId, maxElapsed)
+ if rf, ok := ret.Get(0).(func(context.Context, string, int32, time.Duration) []byte); ok {
+ r0 = rf(ctx, dotId, specId, maxElapsed)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]byte)
}
}
- if rf, ok := ret.Get(1).(func(string, int32, time.Duration) error); ok {
- r1 = rf(dotId, specId, maxElapsed)
+ if rf, ok := ret.Get(1).(func(context.Context, string, int32, time.Duration) error); ok {
+ r1 = rf(ctx, dotId, specId, maxElapsed)
} else {
r1 = ret.Error(1)
}
@@ -308,17 +312,17 @@ func (_m *ORM) GetCachedResponse(dotId string, specId int32, maxElapsed time.Dur
return r0, r1
}
-// UpdateBridgeType provides a mock function with given fields: bt, btr
-func (_m *ORM) UpdateBridgeType(bt *bridges.BridgeType, btr *bridges.BridgeTypeRequest) error {
- ret := _m.Called(bt, btr)
+// UpdateBridgeType provides a mock function with given fields: ctx, bt, btr
+func (_m *ORM) UpdateBridgeType(ctx context.Context, bt *bridges.BridgeType, btr *bridges.BridgeTypeRequest) error {
+ ret := _m.Called(ctx, bt, btr)
if len(ret) == 0 {
panic("no return value specified for UpdateBridgeType")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*bridges.BridgeType, *bridges.BridgeTypeRequest) error); ok {
- r0 = rf(bt, btr)
+ if rf, ok := ret.Get(0).(func(context.Context, *bridges.BridgeType, *bridges.BridgeTypeRequest) error); ok {
+ r0 = rf(ctx, bt, btr)
} else {
r0 = ret.Error(0)
}
@@ -326,17 +330,17 @@ func (_m *ORM) UpdateBridgeType(bt *bridges.BridgeType, btr *bridges.BridgeTypeR
return r0
}
-// UpsertBridgeResponse provides a mock function with given fields: dotId, specId, response
-func (_m *ORM) UpsertBridgeResponse(dotId string, specId int32, response []byte) error {
- ret := _m.Called(dotId, specId, response)
+// UpsertBridgeResponse provides a mock function with given fields: ctx, dotId, specId, response
+func (_m *ORM) UpsertBridgeResponse(ctx context.Context, dotId string, specId int32, response []byte) error {
+ ret := _m.Called(ctx, dotId, specId, response)
if len(ret) == 0 {
panic("no return value specified for UpsertBridgeResponse")
}
var r0 error
- if rf, ok := ret.Get(0).(func(string, int32, []byte) error); ok {
- r0 = rf(dotId, specId, response)
+ if rf, ok := ret.Get(0).(func(context.Context, string, int32, []byte) error); ok {
+ r0 = rf(ctx, dotId, specId, response)
} else {
r0 = ret.Error(0)
}
@@ -344,6 +348,26 @@ func (_m *ORM) UpsertBridgeResponse(dotId string, specId int32, response []byte)
return r0
}
+// WithDataSource provides a mock function with given fields: _a0
+func (_m *ORM) WithDataSource(_a0 sqlutil.DataSource) bridges.ORM {
+ ret := _m.Called(_a0)
+
+ if len(ret) == 0 {
+ panic("no return value specified for WithDataSource")
+ }
+
+ var r0 bridges.ORM
+ if rf, ok := ret.Get(0).(func(sqlutil.DataSource) bridges.ORM); ok {
+ r0 = rf(_a0)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(bridges.ORM)
+ }
+ }
+
+ return r0
+}
+
// NewORM creates a new instance of ORM. 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 NewORM(t interface {
diff --git a/core/bridges/orm.go b/core/bridges/orm.go
index f4728ea0662..5dfb42cff58 100644
--- a/core/bridges/orm.go
+++ b/core/bridges/orm.go
@@ -1,6 +1,7 @@
package bridges
import (
+ "context"
"database/sql"
"fmt"
"sync"
@@ -9,53 +10,60 @@ import (
"github.com/jmoiron/sqlx"
pkgerrors "github.com/pkg/errors"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/auth"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
//go:generate mockery --quiet --name ORM --output ./mocks --case=underscore
type ORM interface {
- FindBridge(name BridgeName) (bt BridgeType, err error)
- FindBridges(name []BridgeName) (bts []BridgeType, err error)
- DeleteBridgeType(bt *BridgeType) error
- BridgeTypes(offset int, limit int) ([]BridgeType, int, error)
- CreateBridgeType(bt *BridgeType) error
- UpdateBridgeType(bt *BridgeType, btr *BridgeTypeRequest) error
-
- GetCachedResponse(dotId string, specId int32, maxElapsed time.Duration) ([]byte, error)
- UpsertBridgeResponse(dotId string, specId int32, response []byte) error
-
- ExternalInitiators(offset int, limit int) ([]ExternalInitiator, int, error)
- CreateExternalInitiator(externalInitiator *ExternalInitiator) error
- DeleteExternalInitiator(name string) error
- FindExternalInitiator(eia *auth.Token) (*ExternalInitiator, error)
- FindExternalInitiatorByName(iname string) (exi ExternalInitiator, err error)
+ FindBridge(ctx context.Context, name BridgeName) (bt BridgeType, err error)
+ FindBridges(ctx context.Context, name []BridgeName) (bts []BridgeType, err error)
+ DeleteBridgeType(ctx context.Context, bt *BridgeType) error
+ BridgeTypes(ctx context.Context, offset int, limit int) ([]BridgeType, int, error)
+ CreateBridgeType(ctx context.Context, bt *BridgeType) error
+ UpdateBridgeType(ctx context.Context, bt *BridgeType, btr *BridgeTypeRequest) error
+
+ GetCachedResponse(ctx context.Context, dotId string, specId int32, maxElapsed time.Duration) ([]byte, error)
+ UpsertBridgeResponse(ctx context.Context, dotId string, specId int32, response []byte) error
+
+ ExternalInitiators(ctx context.Context, offset int, limit int) ([]ExternalInitiator, int, error)
+ CreateExternalInitiator(ctx context.Context, externalInitiator *ExternalInitiator) error
+ DeleteExternalInitiator(ctx context.Context, name string) error
+ FindExternalInitiator(ctx context.Context, eia *auth.Token) (*ExternalInitiator, error)
+ FindExternalInitiatorByName(ctx context.Context, iname string) (exi ExternalInitiator, err error)
+
+ WithDataSource(sqlutil.DataSource) ORM
}
type orm struct {
- q pg.Q
+ ds sqlutil.DataSource
bridgeTypesCache sync.Map
}
var _ ORM = (*orm)(nil)
-func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) ORM {
- namedLogger := lggr.Named("BridgeORM")
- return &orm{q: pg.NewQ(db, namedLogger, cfg)}
+func NewORM(ds sqlutil.DataSource) ORM {
+ return &orm{ds: ds}
+}
+
+func (o *orm) WithDataSource(ds sqlutil.DataSource) ORM { return NewORM(ds) }
+
+func (o *orm) transact(ctx context.Context, readOnly bool, fn func(tx *orm) error) error {
+ opts := sqlutil.TxOptions{TxOptions: sql.TxOptions{ReadOnly: readOnly}}
+ return sqlutil.Transact(ctx, func(ds sqlutil.DataSource) *orm { return &orm{ds: ds} }, o.ds, &opts, fn)
}
// FindBridge looks up a Bridge by its Name.
// Returns sql.ErrNoRows if name not present
-func (o *orm) FindBridge(name BridgeName) (bt BridgeType, err error) {
+func (o *orm) FindBridge(ctx context.Context, name BridgeName) (bt BridgeType, err error) {
if bridgeType, ok := o.bridgeTypesCache.Load(name); ok {
return bridgeType.(BridgeType), nil
}
stmt := "SELECT * FROM bridge_types WHERE name = $1"
- err = o.q.Get(&bt, stmt, name.String())
+ err = o.ds.GetContext(ctx, &bt, stmt, name.String())
if err == nil {
o.bridgeTypesCache.Store(bt.Name, bt)
}
@@ -65,7 +73,7 @@ func (o *orm) FindBridge(name BridgeName) (bt BridgeType, err error) {
// FindBridges looks up multiple bridges in a single query.
// Errors unless all bridges successfully found. Requires at least one bridge.
// Expects all bridges to be unique
-func (o *orm) FindBridges(names []BridgeName) (bts []BridgeType, err error) {
+func (o *orm) FindBridges(ctx context.Context, names []BridgeName) (bts []BridgeType, err error) {
if len(names) == 0 {
return nil, pkgerrors.Errorf("at least one bridge name is required")
}
@@ -90,7 +98,7 @@ func (o *orm) FindBridges(names []BridgeName) (bts []BridgeType, err error) {
if err != nil {
return nil, err
}
- err = o.q.Select(&bts, o.q.Rebind(query), args...)
+ err = o.ds.SelectContext(ctx, &bts, o.ds.Rebind(query), args...)
if err != nil {
return nil, err
}
@@ -105,9 +113,9 @@ func (o *orm) FindBridges(names []BridgeName) (bts []BridgeType, err error) {
}
// DeleteBridgeType removes the bridge type
-func (o *orm) DeleteBridgeType(bt *BridgeType) error {
+func (o *orm) DeleteBridgeType(ctx context.Context, bt *BridgeType) error {
query := "DELETE FROM bridge_types WHERE name = $1"
- result, err := o.q.Exec(query, bt.Name)
+ result, err := o.ds.ExecContext(ctx, query, bt.Name)
if err != nil {
return err
}
@@ -125,33 +133,33 @@ func (o *orm) DeleteBridgeType(bt *BridgeType) error {
// BridgeTypes returns bridge types ordered by name filtered limited by the
// passed params.
-func (o *orm) BridgeTypes(offset int, limit int) (bridges []BridgeType, count int, err error) {
- err = o.q.Transaction(func(tx pg.Queryer) error {
- if err = tx.Get(&count, "SELECT COUNT(*) FROM bridge_types"); err != nil {
+func (o *orm) BridgeTypes(ctx context.Context, offset int, limit int) (bridges []BridgeType, count int, err error) {
+ err = o.transact(ctx, true, func(tx *orm) error {
+ if err = tx.ds.GetContext(ctx, &count, "SELECT COUNT(*) FROM bridge_types"); err != nil {
return pkgerrors.Wrap(err, "BridgeTypes failed to get count")
}
sql := `SELECT * FROM bridge_types ORDER BY name asc LIMIT $1 OFFSET $2;`
- if err = tx.Select(&bridges, sql, limit, offset); err != nil {
+ if err = tx.ds.SelectContext(ctx, &bridges, sql, limit, offset); err != nil {
return pkgerrors.Wrap(err, "BridgeTypes failed to load bridge_types")
}
return nil
- }, pg.OptReadOnlyTx())
+ })
return
}
// CreateBridgeType saves the bridge type.
-func (o *orm) CreateBridgeType(bt *BridgeType) error {
+func (o *orm) CreateBridgeType(ctx context.Context, bt *BridgeType) error {
stmt := `INSERT INTO bridge_types (name, url, confirmations, incoming_token_hash, salt, outgoing_token, minimum_contract_payment, created_at, updated_at)
VALUES (:name, :url, :confirmations, :incoming_token_hash, :salt, :outgoing_token, :minimum_contract_payment, now(), now())
RETURNING *;`
- err := o.q.Transaction(func(tx pg.Queryer) error {
- stmt, err := tx.PrepareNamed(stmt)
+ err := o.transact(ctx, false, func(tx *orm) error {
+ stmt, err := tx.ds.PrepareNamedContext(ctx, stmt)
if err != nil {
return err
}
defer stmt.Close()
- return stmt.Get(bt, bt)
+ return stmt.GetContext(ctx, bt, bt)
})
if err == nil {
o.bridgeTypesCache.Store(bt.Name, *bt)
@@ -161,9 +169,9 @@ func (o *orm) CreateBridgeType(bt *BridgeType) error {
}
// UpdateBridgeType updates the bridge type.
-func (o *orm) UpdateBridgeType(bt *BridgeType, btr *BridgeTypeRequest) error {
+func (o *orm) UpdateBridgeType(ctx context.Context, bt *BridgeType, btr *BridgeTypeRequest) error {
stmt := "UPDATE bridge_types SET url = $1, confirmations = $2, minimum_contract_payment = $3 WHERE name = $4 RETURNING *"
- err := o.q.Get(bt, stmt, btr.URL, btr.Confirmations, btr.MinimumContractPayment, bt.Name)
+ err := o.ds.GetContext(ctx, bt, stmt, btr.URL, btr.Confirmations, btr.MinimumContractPayment, bt.Name)
if err == nil {
o.bridgeTypesCache.Store(bt.Name, *bt)
}
@@ -171,7 +179,7 @@ func (o *orm) UpdateBridgeType(bt *BridgeType, btr *BridgeTypeRequest) error {
return err
}
-func (o *orm) GetCachedResponse(dotId string, specId int32, maxElapsed time.Duration) (response []byte, err error) {
+func (o *orm) GetCachedResponse(ctx context.Context, dotId string, specId int32, maxElapsed time.Duration) (response []byte, err error) {
stalenessThreshold := time.Now().Add(-maxElapsed)
sql := `SELECT value FROM bridge_last_value WHERE
dot_id = $1 AND
@@ -179,62 +187,60 @@ func (o *orm) GetCachedResponse(dotId string, specId int32, maxElapsed time.Dura
finished_at > ($3)
ORDER BY finished_at
DESC LIMIT 1;`
- err = pkgerrors.Wrap(o.q.Get(&response, sql, dotId, specId, stalenessThreshold), fmt.Sprintf("failed to fetch last good value for task %s spec %d", dotId, specId))
+ err = pkgerrors.Wrap(o.ds.GetContext(ctx, &response, sql, dotId, specId, stalenessThreshold), fmt.Sprintf("failed to fetch last good value for task %s spec %d", dotId, specId))
return
}
-func (o *orm) UpsertBridgeResponse(dotId string, specId int32, response []byte) error {
+func (o *orm) UpsertBridgeResponse(ctx context.Context, dotId string, specId int32, response []byte) error {
sql := `INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at)
VALUES($1, $2, $3, $4)
ON CONFLICT ON CONSTRAINT bridge_last_value_pkey
DO UPDATE SET value = $3, finished_at = $4;`
- err := o.q.ExecQ(sql, dotId, specId, response, time.Now())
+ _, err := o.ds.ExecContext(ctx, sql, dotId, specId, response, time.Now())
return pkgerrors.Wrap(err, "failed to upsert bridge response")
}
// --- External Initiator
// ExternalInitiators returns a list of external initiators sorted by name
-func (o *orm) ExternalInitiators(offset int, limit int) (exis []ExternalInitiator, count int, err error) {
- err = o.q.Transaction(func(tx pg.Queryer) error {
- if err = tx.Get(&count, "SELECT COUNT(*) FROM external_initiators"); err != nil {
+func (o *orm) ExternalInitiators(ctx context.Context, offset int, limit int) (exis []ExternalInitiator, count int, err error) {
+ err = o.transact(ctx, true, func(tx *orm) error {
+ if err = tx.ds.GetContext(ctx, &count, "SELECT COUNT(*) FROM external_initiators"); err != nil {
return pkgerrors.Wrap(err, "ExternalInitiators failed to get count")
}
sql := `SELECT * FROM external_initiators ORDER BY name asc LIMIT $1 OFFSET $2;`
- if err = tx.Select(&exis, sql, limit, offset); err != nil {
+ if err = tx.ds.SelectContext(ctx, &exis, sql, limit, offset); err != nil {
return pkgerrors.Wrap(err, "ExternalInitiators failed to load external_initiators")
}
return nil
- }, pg.OptReadOnlyTx())
+ })
return
}
// CreateExternalInitiator inserts a new external initiator
-func (o *orm) CreateExternalInitiator(externalInitiator *ExternalInitiator) (err error) {
+func (o *orm) CreateExternalInitiator(ctx context.Context, externalInitiator *ExternalInitiator) (err error) {
query := `INSERT INTO external_initiators (name, url, access_key, salt, hashed_secret, outgoing_secret, outgoing_token, created_at, updated_at)
VALUES (:name, :url, :access_key, :salt, :hashed_secret, :outgoing_secret, :outgoing_token, now(), now())
RETURNING *
`
- err = o.q.Transaction(func(tx pg.Queryer) error {
+ err = o.transact(ctx, false, func(tx *orm) error {
var stmt *sqlx.NamedStmt
- stmt, err = tx.PrepareNamed(query)
+ stmt, err = tx.ds.PrepareNamedContext(ctx, query)
if err != nil {
return pkgerrors.Wrap(err, "failed to prepare named stmt")
}
defer stmt.Close()
- return pkgerrors.Wrap(stmt.Get(externalInitiator, externalInitiator), "failed to load external_initiator")
+ return pkgerrors.Wrap(stmt.GetContext(ctx, externalInitiator, externalInitiator), "failed to load external_initiator")
})
return pkgerrors.Wrap(err, "CreateExternalInitiator failed")
}
// DeleteExternalInitiator removes an external initiator
-func (o *orm) DeleteExternalInitiator(name string) error {
+func (o *orm) DeleteExternalInitiator(ctx context.Context, name string) error {
query := "DELETE FROM external_initiators WHERE name = $1"
- ctx, cancel := o.q.Context()
- defer cancel()
- result, err := o.q.ExecContext(ctx, query, name)
+ result, err := o.ds.ExecContext(ctx, query, name)
if err != nil {
return err
}
@@ -249,16 +255,14 @@ func (o *orm) DeleteExternalInitiator(name string) error {
}
// FindExternalInitiator finds an external initiator given an authentication request
-func (o *orm) FindExternalInitiator(
- eia *auth.Token,
-) (*ExternalInitiator, error) {
+func (o *orm) FindExternalInitiator(ctx context.Context, eia *auth.Token) (*ExternalInitiator, error) {
exi := &ExternalInitiator{}
- err := o.q.Get(exi, `SELECT * FROM external_initiators WHERE access_key = $1`, eia.AccessKey)
+ err := o.ds.GetContext(ctx, exi, `SELECT * FROM external_initiators WHERE access_key = $1`, eia.AccessKey)
return exi, err
}
// FindExternalInitiatorByName finds an external initiator given an authentication request
-func (o *orm) FindExternalInitiatorByName(iname string) (exi ExternalInitiator, err error) {
- err = o.q.Get(&exi, `SELECT * FROM external_initiators WHERE lower(name) = lower($1)`, iname)
+func (o *orm) FindExternalInitiatorByName(ctx context.Context, iname string) (exi ExternalInitiator, err error) {
+ err = o.ds.GetContext(ctx, &exi, `SELECT * FROM external_initiators WHERE lower(name) = lower($1)`, iname)
return
}
diff --git a/core/bridges/orm_test.go b/core/bridges/orm_test.go
index 0b485764c8b..85e8b9ecdef 100644
--- a/core/bridges/orm_test.go
+++ b/core/bridges/orm_test.go
@@ -17,7 +17,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
)
@@ -25,9 +24,8 @@ import (
func setupORM(t *testing.T) (*sqlx.DB, bridges.ORM) {
t.Helper()
- cfg := configtest.NewGeneralConfig(t, nil)
db := pgtest.NewSqlxDB(t)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
+ orm := bridges.NewORM(db)
return db, orm
}
@@ -40,43 +38,45 @@ func TestORM_FindBridges(t *testing.T) {
Name: "bridge1",
URL: cltest.WebURL(t, "https://bridge1.com"),
}
- assert.NoError(t, orm.CreateBridgeType(&bt))
+ ctx := testutils.Context(t)
+ assert.NoError(t, orm.CreateBridgeType(ctx, &bt))
bt2 := bridges.BridgeType{
Name: "bridge2",
URL: cltest.WebURL(t, "https://bridge2.com"),
}
- assert.NoError(t, orm.CreateBridgeType(&bt2))
- bts, err := orm.FindBridges([]bridges.BridgeName{"bridge2", "bridge1"})
+ assert.NoError(t, orm.CreateBridgeType(ctx, &bt2))
+ bts, err := orm.FindBridges(ctx, []bridges.BridgeName{"bridge2", "bridge1"})
require.NoError(t, err)
require.Equal(t, 2, len(bts))
- bts, err = orm.FindBridges([]bridges.BridgeName{"bridge1"})
+ bts, err = orm.FindBridges(ctx, []bridges.BridgeName{"bridge1"})
require.NoError(t, err)
require.Equal(t, 1, len(bts))
require.Equal(t, "bridge1", bts[0].Name.String())
// One invalid bridge errors
- bts, err = orm.FindBridges([]bridges.BridgeName{"bridge1", "bridgeX"})
+ bts, err = orm.FindBridges(ctx, []bridges.BridgeName{"bridge1", "bridgeX"})
require.Error(t, err, bts)
// All invalid bridges error
- bts, err = orm.FindBridges([]bridges.BridgeName{"bridgeY", "bridgeX"})
+ bts, err = orm.FindBridges(ctx, []bridges.BridgeName{"bridgeY", "bridgeX"})
require.Error(t, err, bts)
// Requires at least one bridge
- bts, err = orm.FindBridges([]bridges.BridgeName{})
+ bts, err = orm.FindBridges(ctx, []bridges.BridgeName{})
require.Error(t, err, bts)
}
func TestORM_FindBridge(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
_, orm := setupORM(t)
bt := bridges.BridgeType{}
bt.Name = bridges.MustParseBridgeName("solargridreporting")
bt.URL = cltest.WebURL(t, "https://denergy.eth")
- assert.NoError(t, orm.CreateBridgeType(&bt))
+ assert.NoError(t, orm.CreateBridgeType(ctx, &bt))
cases := []struct {
description string
@@ -91,7 +91,7 @@ func TestORM_FindBridge(t *testing.T) {
for _, test := range cases {
t.Run(test.description, func(t *testing.T) {
- tt, err := orm.FindBridge(test.name)
+ tt, err := orm.FindBridge(ctx, test.name)
tt.CreatedAt = test.want.CreatedAt
tt.UpdatedAt = test.want.UpdatedAt
if test.errored {
@@ -104,6 +104,7 @@ func TestORM_FindBridge(t *testing.T) {
}
}
func TestORM_UpdateBridgeType(t *testing.T) {
+ ctx := testutils.Context(t)
_, orm := setupORM(t)
firstBridge := &bridges.BridgeType{
@@ -111,53 +112,55 @@ func TestORM_UpdateBridgeType(t *testing.T) {
URL: cltest.WebURL(t, "http:/oneurl.com"),
}
- require.NoError(t, orm.CreateBridgeType(firstBridge))
+ require.NoError(t, orm.CreateBridgeType(ctx, firstBridge))
updateBridge := &bridges.BridgeTypeRequest{
URL: cltest.WebURL(t, "http:/updatedurl.com"),
}
- require.NoError(t, orm.UpdateBridgeType(firstBridge, updateBridge))
+ require.NoError(t, orm.UpdateBridgeType(ctx, firstBridge, updateBridge))
- foundbridge, err := orm.FindBridge("UniqueName")
+ foundbridge, err := orm.FindBridge(ctx, "UniqueName")
require.NoError(t, err)
require.Equal(t, updateBridge.URL, foundbridge.URL)
- bs, count, err := orm.BridgeTypes(0, 10)
+ bs, count, err := orm.BridgeTypes(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 1, count)
require.Len(t, bs, 1)
- require.NoError(t, orm.DeleteBridgeType(&foundbridge))
+ require.NoError(t, orm.DeleteBridgeType(ctx, &foundbridge))
- bs, count, err = orm.BridgeTypes(0, 10)
+ bs, count, err = orm.BridgeTypes(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 0, count)
require.Len(t, bs, 0)
}
func TestORM_TestCachedResponse(t *testing.T) {
+ ctx := testutils.Context(t)
cfg := configtest.NewGeneralConfig(t, nil)
db := pgtest.NewSqlxDB(t)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
+ orm := bridges.NewORM(db)
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
- _, err = orm.GetCachedResponse("dot", specID, 1*time.Second)
+ _, err = orm.GetCachedResponse(ctx, "dot", specID, 1*time.Second)
require.Error(t, err)
require.Contains(t, err.Error(), "no rows in result set")
- err = orm.UpsertBridgeResponse("dot", specID, []byte{111, 222, 2})
+ err = orm.UpsertBridgeResponse(ctx, "dot", specID, []byte{111, 222, 2})
require.NoError(t, err)
- val, err := orm.GetCachedResponse("dot", specID, 1*time.Second)
+ val, err := orm.GetCachedResponse(ctx, "dot", specID, 1*time.Second)
require.NoError(t, err)
require.Equal(t, []byte{111, 222, 2}, val)
}
func TestORM_CreateExternalInitiator(t *testing.T) {
+ ctx := testutils.Context(t)
_, orm := setupORM(t)
token := auth.NewToken()
@@ -167,14 +170,15 @@ func TestORM_CreateExternalInitiator(t *testing.T) {
}
exi, err := bridges.NewExternalInitiator(token, &req)
require.NoError(t, err)
- require.NoError(t, orm.CreateExternalInitiator(exi))
+ require.NoError(t, orm.CreateExternalInitiator(ctx, exi))
exi2, err := bridges.NewExternalInitiator(token, &req)
require.NoError(t, err)
- require.Contains(t, orm.CreateExternalInitiator(exi2).Error(), `ERROR: duplicate key value violates unique constraint "external_initiators_name_key" (SQLSTATE 23505)`)
+ require.Contains(t, orm.CreateExternalInitiator(ctx, exi2).Error(), `ERROR: duplicate key value violates unique constraint "external_initiators_name_key" (SQLSTATE 23505)`)
}
func TestORM_DeleteExternalInitiator(t *testing.T) {
+ ctx := testutils.Context(t)
_, orm := setupORM(t)
token := auth.NewToken()
@@ -184,20 +188,20 @@ func TestORM_DeleteExternalInitiator(t *testing.T) {
}
exi, err := bridges.NewExternalInitiator(token, &req)
require.NoError(t, err)
- require.NoError(t, orm.CreateExternalInitiator(exi))
+ require.NoError(t, orm.CreateExternalInitiator(ctx, exi))
- _, err = orm.FindExternalInitiator(token)
+ _, err = orm.FindExternalInitiator(ctx, token)
require.NoError(t, err)
- _, err = orm.FindExternalInitiatorByName(exi.Name)
+ _, err = orm.FindExternalInitiatorByName(ctx, exi.Name)
require.NoError(t, err)
- err = orm.DeleteExternalInitiator(exi.Name)
+ err = orm.DeleteExternalInitiator(ctx, exi.Name)
require.NoError(t, err)
- _, err = orm.FindExternalInitiator(token)
+ _, err = orm.FindExternalInitiator(ctx, token)
require.Error(t, err)
- _, err = orm.FindExternalInitiatorByName(exi.Name)
+ _, err = orm.FindExternalInitiatorByName(ctx, exi.Name)
require.Error(t, err)
- require.NoError(t, orm.CreateExternalInitiator(exi))
+ require.NoError(t, orm.CreateExternalInitiator(ctx, exi))
}
diff --git a/core/capabilities/registry_test.go b/core/capabilities/registry_test.go
index 3f8ca397495..3bed31a957a 100644
--- a/core/capabilities/registry_test.go
+++ b/core/capabilities/registry_test.go
@@ -19,8 +19,8 @@ type mockCapability struct {
capabilities.CapabilityInfo
}
-func (m *mockCapability) Execute(ctx context.Context, callback chan<- capabilities.CapabilityResponse, req capabilities.CapabilityRequest) error {
- return nil
+func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) {
+ return nil, nil
}
func (m *mockCapability) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error {
@@ -140,7 +140,7 @@ func TestRegistry_ChecksExecutionAPIByType(t *testing.T) {
{
name: "trigger",
newCapability: func(ctx context.Context, reg *coreCapabilities.Registry) (string, error) {
- odt := triggers.NewOnDemand()
+ odt := triggers.NewOnDemand(logger.TestLogger(t))
info, err := odt.Info(ctx)
require.NoError(t, err)
return info.ID, reg.Add(ctx, odt)
diff --git a/core/capabilities/remote/target.go b/core/capabilities/remote/target.go
index bacc06c0310..92b0724512a 100644
--- a/core/capabilities/remote/target.go
+++ b/core/capabilities/remote/target.go
@@ -50,7 +50,7 @@ func (c *remoteTargetCaller) UnregisterFromWorkflow(ctx context.Context, request
return errors.New("not implemented")
}
-func (c *remoteTargetCaller) Execute(ctx context.Context, callback chan<- commoncap.CapabilityResponse, request commoncap.CapabilityRequest) error {
+func (c *remoteTargetCaller) Execute(ctx context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) {
c.lggr.Debugw("not implemented - executing fake remote target capability", "capabilityId", c.capInfo.ID, "nMembers", len(c.donInfo.Members))
for _, peerID := range c.donInfo.Members {
m := &types.MessageBody{
@@ -60,10 +60,12 @@ func (c *remoteTargetCaller) Execute(ctx context.Context, callback chan<- common
}
err := c.dispatcher.Send(peerID, m)
if err != nil {
- return err
+ return nil, err
}
}
- return nil
+
+ // TODO: return a channel that will be closed when all responses are received
+ return nil, nil
}
func (c *remoteTargetCaller) Receive(msg *types.MessageBody) {
diff --git a/core/capabilities/remote/target_test.go b/core/capabilities/remote/target_test.go
index 904cd5b9c71..a9e72d778df 100644
--- a/core/capabilities/remote/target_test.go
+++ b/core/capabilities/remote/target_test.go
@@ -3,8 +3,8 @@ package remote_test
import (
"testing"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
- "github.com/stretchr/testify/require"
commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/remote"
@@ -24,5 +24,7 @@ func TestTarget_Placeholder(t *testing.T) {
dispatcher := remoteMocks.NewDispatcher(t)
dispatcher.On("Send", mock.Anything, mock.Anything).Return(nil)
target := remote.NewRemoteTargetCaller(commoncap.CapabilityInfo{}, donInfo, dispatcher, lggr)
- require.NoError(t, target.Execute(ctx, nil, commoncap.CapabilityRequest{}))
+
+ _, err := target.Execute(ctx, commoncap.CapabilityRequest{})
+ assert.NoError(t, err)
}
diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go
index 94ca58e6156..d06254657c7 100644
--- a/core/capabilities/remote/trigger_publisher.go
+++ b/core/capabilities/remote/trigger_publisher.go
@@ -5,6 +5,7 @@ import (
sync "sync"
"time"
+ "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/services"
@@ -40,7 +41,7 @@ type registrationKey struct {
}
type pubRegState struct {
- callback chan<- commoncap.CapabilityResponse
+ callback <-chan commoncap.CapabilityResponse
request commoncap.CapabilityRequest
}
@@ -87,17 +88,21 @@ func (p *triggerPublisher) Receive(msg *types.MessageBody) {
key := registrationKey{msg.CallerDonId, req.Metadata.WorkflowID}
nowMs := time.Now().UnixMilli()
p.mu.Lock()
+ defer p.mu.Unlock()
p.messageCache.Insert(key, sender, nowMs, msg.Payload)
+ _, exists := p.registrations[key]
+ if exists {
+ p.lggr.Debugw("trigger registration already exists", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID)
+ return
+ }
// 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)
- p.mu.Unlock()
if !ready {
p.lggr.Debugw("not ready to aggregate yet", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "minRequired", minRequired)
return
}
- agg := NewDefaultModeAggregator(uint32(callerDon.F + 1))
- aggregated, err := agg.Aggregate("", payloads)
+ aggregated, err := AggregateModeRaw(payloads, uint32(callerDon.F+1))
if err != nil {
p.lggr.Errorw("failed to aggregate trigger registrations", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "err", err)
return
@@ -107,10 +112,8 @@ func (p *triggerPublisher) Receive(msg *types.MessageBody) {
p.lggr.Errorw("failed to unmarshal request", "capabilityId", p.capInfo.ID, "err", err)
return
}
- p.mu.Lock()
- callbackCh := make(chan commoncap.CapabilityResponse)
ctx, cancel := p.stopCh.NewCtx()
- err = p.underlying.RegisterTrigger(ctx, callbackCh, unmarshaled)
+ callbackCh, err := p.underlying.RegisterTrigger(ctx, unmarshaled)
cancel()
if err == nil {
p.registrations[key] = &pubRegState{
@@ -123,7 +126,6 @@ func (p *triggerPublisher) Receive(msg *types.MessageBody) {
} else {
p.lggr.Errorw("failed to register trigger", "capabilityId", p.capInfo.ID, "workflowId", req.Metadata.WorkflowID, "err", err)
}
- p.mu.Unlock()
} else {
p.lggr.Errorw("received trigger request with unknown method", "method", msg.Method, "sender", sender)
}
@@ -150,7 +152,6 @@ func (p *triggerPublisher) registrationCleanupLoop() {
cancel()
p.lggr.Infow("unregistered trigger", "capabilityId", p.capInfo.ID, "callerDonID", key.callerDonId, "workflowId", key.workflowId, "err", err)
// after calling UnregisterTrigger, the underlying trigger will not send any more events to the channel
- close(req.callback)
delete(p.registrations, key)
p.messageCache.Delete(key)
}
@@ -160,7 +161,7 @@ func (p *triggerPublisher) registrationCleanupLoop() {
}
}
-func (p *triggerPublisher) triggerEventLoop(callbackCh chan commoncap.CapabilityResponse, key registrationKey) {
+func (p *triggerPublisher) triggerEventLoop(callbackCh <-chan commoncap.CapabilityResponse, key registrationKey) {
defer p.wg.Done()
for {
select {
@@ -171,7 +172,13 @@ func (p *triggerPublisher) triggerEventLoop(callbackCh chan commoncap.Capability
p.lggr.Infow("triggerEventLoop channel closed", "capabilityId", p.capInfo.ID, "workflowId", key.workflowId)
return
}
- p.lggr.Debugw("received trigger event", "capabilityId", p.capInfo.ID, "workflowId", key.workflowId)
+ triggerEvent := capabilities.TriggerEvent{}
+ err := response.Value.UnwrapTo(&triggerEvent)
+ if err != nil {
+ p.lggr.Errorw("can't unwrap trigger event", "capabilityId", p.capInfo.ID, "workflowId", key.workflowId, "err", err)
+ break
+ }
+ p.lggr.Debugw("received trigger event", "capabilityId", p.capInfo.ID, "workflowId", key.workflowId, "triggerEventID", triggerEvent.ID)
marshaled, err := pb.MarshalCapabilityResponse(response)
if err != nil {
p.lggr.Debugw("can't marshal trigger event", "err", err)
@@ -186,7 +193,8 @@ func (p *triggerPublisher) triggerEventLoop(callbackCh chan commoncap.Capability
Metadata: &types.MessageBody_TriggerEventMetadata{
TriggerEventMetadata: &types.TriggerEventMetadata{
// NOTE: optionally introduce batching across workflows as an optimization
- WorkflowIds: []string{key.workflowId},
+ WorkflowIds: []string{key.workflowId},
+ TriggerEventId: triggerEvent.ID,
},
},
}
diff --git a/core/capabilities/remote/trigger_publisher_test.go b/core/capabilities/remote/trigger_publisher_test.go
index 2a31646de5b..dd107e12e61 100644
--- a/core/capabilities/remote/trigger_publisher_test.go
+++ b/core/capabilities/remote/trigger_publisher_test.go
@@ -87,9 +87,9 @@ func (t *testTrigger) Info(_ context.Context) (commoncap.CapabilityInfo, error)
return t.info, nil
}
-func (t *testTrigger) RegisterTrigger(_ context.Context, _ chan<- commoncap.CapabilityResponse, request commoncap.CapabilityRequest) error {
+func (t *testTrigger) RegisterTrigger(_ context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) {
t.registrationsCh <- request
- return nil
+ return nil, nil
}
func (t *testTrigger) UnregisterTrigger(_ context.Context, request commoncap.CapabilityRequest) error {
diff --git a/core/capabilities/remote/trigger_subscriber.go b/core/capabilities/remote/trigger_subscriber.go
index 2c893d2b86e..a7cb58c008b 100644
--- a/core/capabilities/remote/trigger_subscriber.go
+++ b/core/capabilities/remote/trigger_subscriber.go
@@ -51,7 +51,11 @@ var _ commoncap.TriggerCapability = &triggerSubscriber{}
var _ types.Receiver = &triggerSubscriber{}
var _ services.Service = &triggerSubscriber{}
-func NewTriggerSubscriber(config types.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo types.DON, localDonInfo types.DON, dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber {
+// TODO makes this configurable with a default
+const defaultSendChannelBufferSize = 1000
+
+func NewTriggerSubscriber(config types.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo types.DON, localDonInfo types.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))
@@ -88,21 +92,25 @@ func (s *triggerSubscriber) Info(ctx context.Context) (commoncap.CapabilityInfo,
return s.capInfo, nil
}
-func (s *triggerSubscriber) RegisterTrigger(ctx context.Context, callback chan<- commoncap.CapabilityResponse, request commoncap.CapabilityRequest) error {
+func (s *triggerSubscriber) RegisterTrigger(ctx context.Context, request commoncap.CapabilityRequest) (<-chan commoncap.CapabilityResponse, error) {
rawRequest, err := pb.MarshalCapabilityRequest(request)
if err != nil {
- return err
+ return nil, err
}
if request.Metadata.WorkflowID == "" {
- return errors.New("empty workflowID")
+ return nil, errors.New("empty workflowID")
}
s.mu.Lock()
defer s.mu.Unlock()
+
+ callback := make(chan commoncap.CapabilityResponse, defaultSendChannelBufferSize)
s.registeredWorkflows[request.Metadata.WorkflowID] = &subRegState{
callback: callback,
rawRequest: rawRequest,
}
- return nil
+
+ s.lggr.Infow("RegisterTrigger called", "capabilityId", s.capInfo.ID, "donId", s.capDonInfo.ID, "workflowID", request.Metadata.WorkflowID)
+ return callback, nil
}
func (s *triggerSubscriber) registrationLoop() {
@@ -114,8 +122,8 @@ func (s *triggerSubscriber) registrationLoop() {
case <-s.stopCh:
return
case <-ticker.C:
- s.lggr.Infow("register trigger for remote capability", "capabilityId", s.capInfo.ID, "donId", s.capDonInfo.ID, "nMembers", len(s.capDonInfo.Members))
s.mu.RLock()
+ s.lggr.Infow("register trigger for remote capability", "capabilityId", s.capInfo.ID, "donId", s.capDonInfo.ID, "nMembers", len(s.capDonInfo.Members), "nWorkflows", len(s.registeredWorkflows))
for _, registration := range s.registeredWorkflows {
// NOTE: send to all by default, introduce different strategies later (KS-76)
for _, peerID := range s.capDonInfo.Members {
@@ -140,6 +148,8 @@ func (s *triggerSubscriber) registrationLoop() {
func (s *triggerSubscriber) UnregisterTrigger(ctx context.Context, request commoncap.CapabilityRequest) error {
s.mu.Lock()
defer s.mu.Unlock()
+
+ close(s.registeredWorkflows[request.Metadata.WorkflowID].callback)
delete(s.registeredWorkflows, request.Metadata.WorkflowID)
// Registrations will quickly expire on all remote nodes.
// Alternatively, we could send UnregisterTrigger messages right away.
@@ -180,18 +190,14 @@ func (s *triggerSubscriber) Receive(msg *types.MessageBody) {
continue
}
if ready {
+ s.lggr.Debugw("trigger event ready to aggregate", "triggerEventID", meta.TriggerEventId, "capabilityId", s.capInfo.ID, "workflowId", workflowId)
aggregatedResponse, err := s.aggregator.Aggregate(meta.TriggerEventId, payloads)
if err != nil {
- s.lggr.Errorw("failed to aggregate responses", "capabilityId", s.capInfo.ID, "workflowId", workflowId, "err", err)
- continue
- }
- unmarshaled, err := pb.UnmarshalCapabilityResponse(aggregatedResponse)
- if err != nil {
- s.lggr.Errorw("failed to unmarshal responses", "capabilityId", s.capInfo.ID, "workflowId", workflowId, "err", err)
+ s.lggr.Errorw("failed to aggregate responses", "triggerEventID", meta.TriggerEventId, "capabilityId", s.capInfo.ID, "workflowId", workflowId, "err", err)
continue
}
- s.lggr.Info("remote trigger event aggregated", "triggerEventID", meta.TriggerEventId, "capabilityId", s.capInfo.ID, "workflowId", workflowId)
- registration.callback <- unmarshaled
+ s.lggr.Infow("remote trigger event aggregated", "triggerEventID", meta.TriggerEventId, "capabilityId", s.capInfo.ID, "workflowId", workflowId)
+ registration.callback <- aggregatedResponse
}
}
} else {
diff --git a/core/capabilities/remote/trigger_subscriber_test.go b/core/capabilities/remote/trigger_subscriber_test.go
index ce901169f10..df04306e2b0 100644
--- a/core/capabilities/remote/trigger_subscriber_test.go
+++ b/core/capabilities/remote/trigger_subscriber_test.go
@@ -67,12 +67,13 @@ func TestTriggerSubscriber_RegisterAndReceive(t *testing.T) {
}
subscriber := remote.NewTriggerSubscriber(config, capInfo, capDonInfo, workflowDonInfo, dispatcher, nil, lggr)
require.NoError(t, subscriber.Start(ctx))
- triggerEventCallbackCh := make(chan commoncap.CapabilityResponse, 2)
- require.NoError(t, subscriber.RegisterTrigger(ctx, triggerEventCallbackCh, commoncap.CapabilityRequest{
+
+ triggerEventCallbackCh, err := subscriber.RegisterTrigger(ctx, commoncap.CapabilityRequest{
Metadata: commoncap.RequestMetadata{
WorkflowID: workflowID1,
},
- }))
+ })
+ require.NoError(t, err)
<-awaitRegistrationMessageCh
// receive trigger event
diff --git a/core/capabilities/remote/types/types.go b/core/capabilities/remote/types/types.go
index 327c2b8d4c5..d8307d09f80 100644
--- a/core/capabilities/remote/types/types.go
+++ b/core/capabilities/remote/types/types.go
@@ -1,6 +1,7 @@
package types
import (
+ commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
)
@@ -23,7 +24,7 @@ type Receiver interface {
}
type Aggregator interface {
- Aggregate(eventID string, responses [][]byte) ([]byte, error)
+ Aggregate(eventID string, responses [][]byte) (commoncap.CapabilityResponse, error)
}
// NOTE: this type will become part of the Registry (KS-108)
diff --git a/core/capabilities/remote/utils.go b/core/capabilities/remote/utils.go
index 92c5e5447a5..dba24b843cc 100644
--- a/core/capabilities/remote/utils.go
+++ b/core/capabilities/remote/utils.go
@@ -10,6 +10,8 @@ import (
"google.golang.org/protobuf/proto"
+ commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
)
@@ -60,16 +62,29 @@ func NewDefaultModeAggregator(minIdenticalResponses uint32) *defaultModeAggregat
}
}
-func (a *defaultModeAggregator) Aggregate(_ string, responses [][]byte) ([]byte, error) {
+func (a *defaultModeAggregator) Aggregate(_ string, responses [][]byte) (commoncap.CapabilityResponse, error) {
+ found, err := AggregateModeRaw(responses, a.minIdenticalResponses)
+ if err != nil {
+ return commoncap.CapabilityResponse{}, fmt.Errorf("failed to aggregate responses, err: %w", err)
+ }
+
+ unmarshaled, err := pb.UnmarshalCapabilityResponse(found)
+ if err != nil {
+ return commoncap.CapabilityResponse{}, fmt.Errorf("failed to unmarshal aggregated responses, err: %w", err)
+ }
+ return unmarshaled, nil
+}
+
+func AggregateModeRaw(elemList [][]byte, minIdenticalResponses uint32) ([]byte, error) {
hashToCount := make(map[string]uint32)
var found []byte
- for _, resp := range responses {
+ for _, elem := range elemList {
hasher := sha256.New()
- hasher.Write(resp)
+ hasher.Write(elem)
sha := hex.EncodeToString(hasher.Sum(nil))
hashToCount[sha]++
- if hashToCount[sha] >= a.minIdenticalResponses {
- found = resp
+ if hashToCount[sha] >= minIdenticalResponses {
+ found = elem
break
}
}
diff --git a/core/capabilities/remote/utils_test.go b/core/capabilities/remote/utils_test.go
index 120cf5604ca..b5f97af99ed 100644
--- a/core/capabilities/remote/utils_test.go
+++ b/core/capabilities/remote/utils_test.go
@@ -1,7 +1,6 @@
package remote_test
import (
- "bytes"
"crypto/ed25519"
"crypto/rand"
"testing"
@@ -90,29 +89,32 @@ func TestToPeerID(t *testing.T) {
}
func TestDefaultModeAggregator_Aggregate(t *testing.T) {
- capResponse1 := marshalCapabilityResponse(t, triggerEvent1, nil)
- capResponse2 := marshalCapabilityResponse(t, triggerEvent2, nil)
+ val, err := values.Wrap(triggerEvent1)
+ require.NoError(t, err)
+ capResponse1 := commoncap.CapabilityResponse{
+ Value: val,
+ Err: nil,
+ }
+ marshaled1, err := pb.MarshalCapabilityResponse(capResponse1)
+ require.NoError(t, err)
+
+ val2, err := values.Wrap(triggerEvent2)
+ require.NoError(t, err)
+ capResponse2 := commoncap.CapabilityResponse{
+ Value: val2,
+ Err: nil,
+ }
+ marshaled2, err := pb.MarshalCapabilityResponse(capResponse2)
+ require.NoError(t, err)
agg := remote.NewDefaultModeAggregator(2)
- _, err := agg.Aggregate("", [][]byte{capResponse1})
+ _, err = agg.Aggregate("", [][]byte{marshaled1})
require.Error(t, err)
- _, err = agg.Aggregate("", [][]byte{capResponse1, capResponse2})
+ _, err = agg.Aggregate("", [][]byte{marshaled1, marshaled2})
require.Error(t, err)
- res, err := agg.Aggregate("", [][]byte{capResponse1, capResponse2, capResponse1})
- require.NoError(t, err)
- require.True(t, bytes.Equal(res, capResponse1))
-}
-
-func marshalCapabilityResponse(t *testing.T, capValue any, capError error) []byte {
- val, err := values.Wrap(capValue)
- require.NoError(t, err)
- capResponse := commoncap.CapabilityResponse{
- Value: val,
- Err: capError,
- }
- marshaled, err := pb.MarshalCapabilityResponse(capResponse)
+ res, err := agg.Aggregate("", [][]byte{marshaled1, marshaled2, marshaled1})
require.NoError(t, err)
- return marshaled
+ require.Equal(t, res, capResponse1)
}
diff --git a/core/capabilities/syncer.go b/core/capabilities/syncer.go
index 748910c462b..2de917b5f9f 100644
--- a/core/capabilities/syncer.go
+++ b/core/capabilities/syncer.go
@@ -3,8 +3,12 @@ package capabilities
import (
"context"
"slices"
+ "sync"
+ "time"
commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/mercury"
+ "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers"
"github.com/smartcontractkit/chainlink-common/pkg/services"
"github.com/smartcontractkit/chainlink-common/pkg/types"
@@ -32,12 +36,12 @@ var defaultStreamConfig = p2ptypes.StreamConfig{
OutgoingMessageBufferSize: 1000000,
MaxMessageLenBytes: 100000,
MessageRateLimiter: ragep2p.TokenBucketParams{
- Rate: 10.0,
+ Rate: 100.0,
Capacity: 1000,
},
BytesRateLimiter: ragep2p.TokenBucketParams{
- Rate: 10.0,
- Capacity: 1000,
+ Rate: 100000.0,
+ Capacity: 1000000,
},
}
@@ -54,14 +58,16 @@ func NewRegistrySyncer(peerWrapper p2ptypes.PeerWrapper, registry types.Capabili
func (s *registrySyncer) Start(ctx context.Context) error {
// NOTE: temporary hard-coded DONs
workflowDONPeers := []string{
- "12D3KooWF3dVeJ6YoT5HFnYhmwQWWMoEwVFzJQ5kKCMX3ZityxMC",
- "12D3KooWQsmok6aD8PZqt3RnJhQRrNzKHLficq7zYFRp7kZ1hHP8",
- "12D3KooWJbZLiMuGeKw78s3LM5TNgBTJHcF39DraxLu14bucG9RN",
- "12D3KooWGqfSPhHKmQycfhRjgUDE2vg9YWZN27Eue8idb2ZUk6EH",
+ "12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N",
+ "12D3KooWG1AyvwmCpZ93J8pBQUE1SuzrjDXnT4BeouncHR3jWLCG",
+ "12D3KooWGeUKZBRMbx27FUTgBwZa9Ap9Ym92mywwpuqkEtz8XWyv",
+ "12D3KooW9zYWQv3STmDeNDidyzxsJSTxoCTLicafgfeEz9nhwhC4",
}
- capabilityDONPeers := []string{
- "12D3KooWHCcyTPmYFB1ydNvNcXw5WyAomRzGSFu1B7hpB4yi8Smf",
- "12D3KooWPv6eqJvYz7TcQWk4Y4XjZ1uQ7mUKahdDXj65ht95zH6a",
+ triggerDONPeers := []string{
+ "12D3KooWJrthXtnPHw7xyHFAxo6NxifYTvc8igKYaA6wRRRqtsMb",
+ "12D3KooWFQekP9sGex4XhqEJav5EScjTpDVtDqJFg1JvrePBCEGJ",
+ "12D3KooWFLEq4hYtdyKWwe47dXGEbSiHMZhmr5xLSJNhpfiEz8NF",
+ "12D3KooWN2hztiXNNS1jMQTTvvPRYcarK1C7T3Mdqk4x4gwyo5WS",
}
allPeers := make(map[ragetypes.PeerID]p2ptypes.StreamConfig)
addPeersToDONInfo := func(peers []string, donInfo *remotetypes.DON) error {
@@ -76,12 +82,12 @@ func (s *registrySyncer) Start(ctx context.Context) error {
}
return nil
}
- workflowDonInfo := remotetypes.DON{ID: "workflowDon1"}
+ workflowDonInfo := remotetypes.DON{ID: "workflowDon1", F: 1}
if err := addPeersToDONInfo(workflowDONPeers, &workflowDonInfo); err != nil {
return err
}
- capabilityDonInfo := remotetypes.DON{ID: "capabilityDon1"}
- if err := addPeersToDONInfo(capabilityDONPeers, &capabilityDonInfo); err != nil {
+ triggerCapabilityDonInfo := remotetypes.DON{ID: "capabilityDon1", F: 1}
+ if err := addPeersToDONInfo(triggerDONPeers, &triggerCapabilityDonInfo); err != nil {
return err
}
err := s.peerWrapper.GetPeer().UpdateConnections(allPeers)
@@ -89,7 +95,7 @@ func (s *registrySyncer) Start(ctx context.Context) error {
return err
}
// NOTE: temporary hard-coded capabilities
- capId := "sample_remote_trigger"
+ capId := "mercury-trigger"
triggerInfo := commoncap.CapabilityInfo{
ID: capId,
CapabilityType: commoncap.CapabilityTypeTrigger,
@@ -98,36 +104,42 @@ func (s *registrySyncer) Start(ctx context.Context) error {
}
myId := s.peerWrapper.GetPeer().ID().String()
config := remotetypes.RemoteTriggerConfig{
- RegistrationRefreshMs: 20000,
+ RegistrationRefreshMs: 20000,
+ MinResponsesToAggregate: uint32(triggerCapabilityDonInfo.F) + 1,
}
if slices.Contains(workflowDONPeers, myId) {
s.lggr.Info("member of a workflow DON - starting remote subscribers")
- triggerCap := remote.NewTriggerSubscriber(config, triggerInfo, capabilityDonInfo, workflowDonInfo, s.dispatcher, nil, s.lggr)
+ aggregator := triggers.NewMercuryRemoteAggregator(s.lggr)
+ triggerCap := remote.NewTriggerSubscriber(config, triggerInfo, triggerCapabilityDonInfo, workflowDonInfo, s.dispatcher, aggregator, s.lggr)
err = s.registry.Add(ctx, triggerCap)
if err != nil {
s.lggr.Errorw("failed to add remote target capability to registry", "error", err)
return err
}
- err = s.dispatcher.SetReceiver(capId, capabilityDonInfo.ID, triggerCap)
+ err = s.dispatcher.SetReceiver(capId, triggerCapabilityDonInfo.ID, triggerCap)
if err != nil {
- s.lggr.Errorw("failed to set receiver", "capabilityId", capId, "donId", capabilityDonInfo.ID, "error", err)
+ s.lggr.Errorw("workflow DON failed to set receiver", "capabilityId", capId, "donId", triggerCapabilityDonInfo.ID, "error", err)
return err
}
s.subServices = append(s.subServices, triggerCap)
}
- if slices.Contains(capabilityDONPeers, myId) {
+ if slices.Contains(triggerDONPeers, myId) {
s.lggr.Info("member of a capability DON - starting remote publishers")
workflowDONs := map[string]remotetypes.DON{
workflowDonInfo.ID: workflowDonInfo,
}
- underlying := &noOpTrigger{info: triggerInfo, lggr: s.lggr}
- triggerCap := remote.NewTriggerPublisher(config, underlying, triggerInfo, capabilityDonInfo, workflowDONs, s.dispatcher, s.lggr)
- err = s.dispatcher.SetReceiver(capId, capabilityDonInfo.ID, triggerCap)
+ underlying := triggers.NewMercuryTriggerService(1000, s.lggr)
+ triggerCap := remote.NewTriggerPublisher(config, underlying, triggerInfo, triggerCapabilityDonInfo, workflowDONs, s.dispatcher, s.lggr)
+ err = s.dispatcher.SetReceiver(capId, triggerCapabilityDonInfo.ID, triggerCap)
if err != nil {
- s.lggr.Errorw("failed to set receiver", "capabilityId", capId, "donId", capabilityDonInfo.ID, "error", err)
+ s.lggr.Errorw("capability DON failed to set receiver", "capabilityId", capId, "donId", triggerCapabilityDonInfo.ID, "error", err)
return err
}
+ s.subServices = append(s.subServices, underlying)
s.subServices = append(s.subServices, triggerCap)
+ // NOTE: temporary mock Mercury data producer
+ mockMercuryDataProducer := NewMockMercuryDataProducer(underlying, s.lggr)
+ s.subServices = append(s.subServices, mockMercuryDataProducer)
}
// NOTE: temporary service start - should be managed by capability creation
for _, srv := range s.subServices {
@@ -163,21 +175,86 @@ func (s *registrySyncer) Name() string {
return "RegistrySyncer"
}
-type noOpTrigger struct {
- info commoncap.CapabilityInfo
- lggr logger.Logger
+type mockMercuryDataProducer struct {
+ trigger *triggers.MercuryTriggerService
+ wg sync.WaitGroup
+ closeCh chan struct{}
+ lggr logger.Logger
}
-func (t *noOpTrigger) Info(_ context.Context) (commoncap.CapabilityInfo, error) {
- return t.info, nil
+var _ services.Service = &mockMercuryDataProducer{}
+
+func NewMockMercuryDataProducer(trigger *triggers.MercuryTriggerService, lggr logger.Logger) *mockMercuryDataProducer {
+ return &mockMercuryDataProducer{
+ trigger: trigger,
+ closeCh: make(chan struct{}),
+ lggr: lggr,
+ }
}
-func (t *noOpTrigger) RegisterTrigger(_ context.Context, _ chan<- commoncap.CapabilityResponse, request commoncap.CapabilityRequest) error {
- t.lggr.Infow("no-op trigger RegisterTrigger", "workflowID", request.Metadata.WorkflowID)
+func (m *mockMercuryDataProducer) Start(ctx context.Context) error {
+ m.wg.Add(1)
+ go m.loop()
return nil
}
-func (t *noOpTrigger) UnregisterTrigger(_ context.Context, request commoncap.CapabilityRequest) error {
- t.lggr.Infow("no-op trigger RegisterTrigger", "workflowID", request.Metadata.WorkflowID)
+func (m *mockMercuryDataProducer) loop() {
+ defer m.wg.Done()
+
+ sleepSec := 60
+ ticker := time.NewTicker(time.Duration(sleepSec) * time.Second)
+ defer ticker.Stop()
+
+ prices := []int64{300000, 40000, 5000000}
+
+ for range ticker.C {
+ for i := range prices {
+ prices[i] = prices[i] + 1
+ }
+
+ reports := []mercury.FeedReport{
+ {
+ FeedID: "0x1111111111111111111100000000000000000000000000000000000000000000",
+ FullReport: []byte{0x11, 0xaa, 0xbb, 0xcc},
+ BenchmarkPrice: prices[0],
+ ObservationTimestamp: time.Now().Unix(),
+ },
+ {
+ FeedID: "0x2222222222222222222200000000000000000000000000000000000000000000",
+ FullReport: []byte{0x22, 0xaa, 0xbb, 0xcc},
+ BenchmarkPrice: prices[1],
+ ObservationTimestamp: time.Now().Unix(),
+ },
+ {
+ FeedID: "0x3333333333333333333300000000000000000000000000000000000000000000",
+ FullReport: []byte{0x33, 0xaa, 0xbb, 0xcc},
+ BenchmarkPrice: prices[2],
+ ObservationTimestamp: time.Now().Unix(),
+ },
+ }
+
+ m.lggr.Infow("New set of Mercury reports", "timestamp", time.Now().Unix(), "payload", reports)
+ err := m.trigger.ProcessReport(reports)
+ if err != nil {
+ m.lggr.Errorw("failed to process Mercury reports", "err", err, "timestamp", time.Now().Unix(), "payload", reports)
+ }
+ }
+}
+
+func (m *mockMercuryDataProducer) Close() error {
+ close(m.closeCh)
+ m.wg.Wait()
+ return nil
+}
+
+func (m *mockMercuryDataProducer) HealthReport() map[string]error {
return nil
}
+
+func (m *mockMercuryDataProducer) Ready() error {
+ return nil
+}
+
+func (m *mockMercuryDataProducer) Name() string {
+ return "mockMercuryDataProducer"
+}
diff --git a/core/capabilities/syncer_test.go b/core/capabilities/syncer_test.go
index 335b9774689..757135635d8 100644
--- a/core/capabilities/syncer_test.go
+++ b/core/capabilities/syncer_test.go
@@ -20,7 +20,7 @@ func TestSyncer_CleanStartClose(t *testing.T) {
lggr := logger.TestLogger(t)
ctx := testutils.Context(t)
var pid ragetypes.PeerID
- err := pid.UnmarshalText([]byte("12D3KooWF3dVeJ6YoT5HFnYhmwQWWMoEwVFzJQ5kKCMX3ZityxMC"))
+ err := pid.UnmarshalText([]byte("12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N"))
require.NoError(t, err)
peer := mocks.NewPeer(t)
peer.On("UpdateConnections", mock.Anything).Return(nil)
diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go
index 677b1148ebb..43b02939c04 100644
--- a/core/capabilities/targets/write_target.go
+++ b/core/capabilities/targets/write_target.go
@@ -28,7 +28,8 @@ import (
var forwardABI = evmtypes.MustGetABI(forwarder.KeystoneForwarderMetaData.ABI)
-func InitializeWrite(registry commontypes.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer, lggr logger.Logger) error {
+func InitializeWrite(registry commontypes.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer,
+ lggr logger.Logger) error {
for _, chain := range legacyEVMChains.Slice() {
capability := NewEvmWrite(chain, lggr)
if err := registry.Add(context.TODO(), capability); err != nil {
@@ -157,7 +158,7 @@ func encodePayload(args []any, rawSelector string) ([]byte, error) {
// return append(method.ID, arguments...), nil
}
-func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.CapabilityResponse, request capabilities.CapabilityRequest) error {
+func (cap *EvmWrite) Execute(ctx context.Context, request capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) {
cap.lggr.Debugw("Execute", "request", request)
// TODO: idempotency
@@ -168,22 +169,23 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C
reqConfig, err := parseConfig(request.Config)
if err != nil {
- return err
+ return nil, err
}
inputsAny, err := request.Inputs.Unwrap()
if err != nil {
- return err
+ return nil, err
}
inputs := inputsAny.(map[string]any)
rep, ok := inputs["report"]
if !ok {
- return errors.New("malformed data: inputs doesn't contain a report key")
+ return nil, errors.New("malformed data: inputs doesn't contain a report key")
}
if rep == nil {
// We received any empty report -- this means we should skip transmission.
cap.lggr.Debugw("Skipping empty report", "request", request)
+ callback := make(chan capabilities.CapabilityResponse)
go func() {
// TODO: cast tx.Error to Err (or Value to Value?)
callback <- capabilities.CapabilityResponse{
@@ -192,18 +194,18 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C
}
close(callback)
}()
- return nil
+ return callback, nil
}
// evaluate any variables in reqConfig.Params
args, err := evaluateParams(reqConfig.Params, inputs)
if err != nil {
- return err
+ return nil, err
}
data, err := encodePayload(args, reqConfig.ABI)
if err != nil {
- return err
+ return nil, err
}
// TODO: validate encoded report is prefixed with workflowID and executionID that match the request meta
@@ -214,7 +216,7 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C
// construct forwarding payload
calldata, err := forwardABI.Pack("report", common.HexToAddress(reqConfig.Address), data, signatures)
if err != nil {
- return err
+ return nil, err
}
txMeta := &txmgr.TxMeta{
@@ -238,9 +240,11 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C
}
tx, err := txm.CreateTransaction(ctx, req)
if err != nil {
- return err
+ return nil, err
}
cap.lggr.Debugw("Transaction submitted", "request", request, "transaction", tx)
+
+ callback := make(chan capabilities.CapabilityResponse)
go func() {
// TODO: cast tx.Error to Err (or Value to Value?)
callback <- capabilities.CapabilityResponse{
@@ -249,7 +253,7 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C
}
close(callback)
}()
- return nil
+ return callback, nil
}
func (cap *EvmWrite) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error {
diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go
index fd68234ca70..744fcd9d2e7 100644
--- a/core/capabilities/targets/write_target_test.go
+++ b/core/capabilities/targets/write_target_test.go
@@ -82,9 +82,7 @@ func TestEvmWrite(t *testing.T) {
})
- ch := make(chan capabilities.CapabilityResponse)
-
- err = capability.Execute(ctx, ch, req)
+ ch, err := capability.Execute(ctx, req)
require.NoError(t, err)
response := <-ch
@@ -134,9 +132,7 @@ func TestEvmWrite_EmptyReport(t *testing.T) {
Inputs: inputs,
}
- ch := make(chan capabilities.CapabilityResponse)
-
- err = capability.Execute(ctx, ch, req)
+ ch, err := capability.Execute(ctx, req)
require.NoError(t, err)
response := <-ch
diff --git a/core/chainlink.Dockerfile b/core/chainlink.Dockerfile
index e82a4cd662c..4aa447b5ddd 100644
--- a/core/chainlink.Dockerfile
+++ b/core/chainlink.Dockerfile
@@ -45,7 +45,7 @@ RUN apt-get update && apt-get install -y ca-certificates gnupg lsb-release curl
# Install Postgres for CLI tools, needed specifically for DB backups
RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
&& echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |tee /etc/apt/sources.list.d/pgdg.list \
- && apt-get update && apt-get install -y postgresql-client-15 \
+ && apt-get update && apt-get install -y postgresql-client-16 \
&& apt-get clean all \
&& rm -rf /var/lib/apt/lists/*
diff --git a/core/chainlink.goreleaser.Dockerfile b/core/chainlink.goreleaser.Dockerfile
index 7dab088116e..5d172fd77e5 100644
--- a/core/chainlink.goreleaser.Dockerfile
+++ b/core/chainlink.goreleaser.Dockerfile
@@ -11,7 +11,7 @@ RUN apt-get update && apt-get install -y ca-certificates gnupg lsb-release curl
# Install Postgres for CLI tools, needed specifically for DB backups
RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
&& echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |tee /etc/apt/sources.list.d/pgdg.list \
- && apt-get update && apt-get install -y postgresql-client-15 \
+ && apt-get update && apt-get install -y postgresql-client-16 \
&& apt-get clean all \
&& rm -rf /var/lib/apt/lists/*
diff --git a/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml b/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml
index 7769320bb81..c097e2f7e36 100644
--- a/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml
+++ b/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml
@@ -14,7 +14,7 @@ MaxQueued = 5000
Enabled = true
[GasEstimator]
-PriceDefault = '1 gwei'
+EIP1559DynamicFees = true
PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether'
PriceMin = '1 gwei'
BumpMin = '20 gwei'
diff --git a/core/chains/evm/forwarders/forwarder_manager.go b/core/chains/evm/forwarders/forwarder_manager.go
index f0786c091c4..7a7a274127f 100644
--- a/core/chains/evm/forwarders/forwarder_manager.go
+++ b/core/chains/evm/forwarders/forwarder_manager.go
@@ -54,13 +54,13 @@ type FwdMgr struct {
wg sync.WaitGroup
}
-func NewFwdMgr(db sqlutil.DataSource, client evmclient.Client, logpoller evmlogpoller.LogPoller, l logger.Logger, cfg Config) *FwdMgr {
+func NewFwdMgr(ds sqlutil.DataSource, client evmclient.Client, logpoller evmlogpoller.LogPoller, l logger.Logger, cfg Config) *FwdMgr {
lggr := logger.Sugared(logger.Named(l, "EVMForwarderManager"))
fwdMgr := FwdMgr{
logger: lggr,
cfg: cfg,
evmClient: client,
- ORM: NewORM(db),
+ ORM: NewORM(ds),
logpoller: logpoller,
sendersCache: make(map[common.Address][]common.Address),
}
diff --git a/core/chains/evm/forwarders/orm.go b/core/chains/evm/forwarders/orm.go
index cf498518d6d..8076cba4831 100644
--- a/core/chains/evm/forwarders/orm.go
+++ b/core/chains/evm/forwarders/orm.go
@@ -23,50 +23,50 @@ type ORM interface {
FindForwardersInListByChain(ctx context.Context, evmChainId big.Big, addrs []common.Address) ([]Forwarder, error)
}
-type DbORM struct {
- db sqlutil.DataSource
+type DSORM struct {
+ ds sqlutil.DataSource
}
-var _ ORM = &DbORM{}
+var _ ORM = &DSORM{}
-func NewORM(db sqlutil.DataSource) *DbORM {
- return &DbORM{db: db}
+func NewORM(ds sqlutil.DataSource) *DSORM {
+ return &DSORM{ds: ds}
}
-func (o *DbORM) Transaction(ctx context.Context, fn func(*DbORM) error) (err error) {
- return sqlutil.Transact(ctx, o.new, o.db, nil, fn)
+func (o *DSORM) Transact(ctx context.Context, fn func(*DSORM) error) (err error) {
+ return sqlutil.Transact(ctx, o.new, o.ds, nil, fn)
}
// new returns a NewORM like o, but backed by q.
-func (o *DbORM) new(q sqlutil.DataSource) *DbORM { return NewORM(q) }
+func (o *DSORM) new(q sqlutil.DataSource) *DSORM { return NewORM(q) }
// CreateForwarder creates the Forwarder address associated with the current EVM chain id.
-func (o *DbORM) CreateForwarder(ctx context.Context, addr common.Address, evmChainId big.Big) (fwd Forwarder, err error) {
+func (o *DSORM) CreateForwarder(ctx context.Context, addr common.Address, evmChainId big.Big) (fwd Forwarder, err error) {
sql := `INSERT INTO evm.forwarders (address, evm_chain_id, created_at, updated_at) VALUES ($1, $2, now(), now()) RETURNING *`
- err = o.db.GetContext(ctx, &fwd, sql, addr, evmChainId)
+ err = o.ds.GetContext(ctx, &fwd, sql, addr, evmChainId)
return fwd, err
}
// DeleteForwarder removes a forwarder address.
// If cleanup is non-nil, it can be used to perform any chain- or contract-specific cleanup that need to happen atomically
// on forwarder deletion. If cleanup returns an error, forwarder deletion will be aborted.
-func (o *DbORM) DeleteForwarder(ctx context.Context, id int64, cleanup func(tx sqlutil.DataSource, evmChainID int64, addr common.Address) error) (err error) {
- return o.Transaction(ctx, func(orm *DbORM) error {
+func (o *DSORM) DeleteForwarder(ctx context.Context, id int64, cleanup func(tx sqlutil.DataSource, evmChainID int64, addr common.Address) error) (err error) {
+ return o.Transact(ctx, func(orm *DSORM) error {
var dest struct {
EvmChainId int64
Address common.Address
}
- err := orm.db.GetContext(ctx, &dest, `SELECT evm_chain_id, address FROM evm.forwarders WHERE id = $1`, id)
+ err := orm.ds.GetContext(ctx, &dest, `SELECT evm_chain_id, address FROM evm.forwarders WHERE id = $1`, id)
if err != nil {
return err
}
if cleanup != nil {
- if err = cleanup(orm.db, dest.EvmChainId, dest.Address); err != nil {
+ if err = cleanup(orm.ds, dest.EvmChainId, dest.Address); err != nil {
return err
}
}
- result, err := orm.db.ExecContext(ctx, `DELETE FROM evm.forwarders WHERE id = $1`, id)
+ result, err := orm.ds.ExecContext(ctx, `DELETE FROM evm.forwarders WHERE id = $1`, id)
// If the forwarder wasn't found, we still want to delete the filter.
// In that case, the transaction must return nil, even though DeleteForwarder
// will return sql.ErrNoRows
@@ -82,27 +82,27 @@ func (o *DbORM) DeleteForwarder(ctx context.Context, id int64, cleanup func(tx s
}
// FindForwarders returns all forwarder addresses from offset up until limit.
-func (o *DbORM) FindForwarders(ctx context.Context, offset, limit int) (fwds []Forwarder, count int, err error) {
+func (o *DSORM) FindForwarders(ctx context.Context, offset, limit int) (fwds []Forwarder, count int, err error) {
sql := `SELECT count(*) FROM evm.forwarders`
- if err = o.db.GetContext(ctx, &count, sql); err != nil {
+ if err = o.ds.GetContext(ctx, &count, sql); err != nil {
return
}
sql = `SELECT * FROM evm.forwarders ORDER BY created_at DESC, id DESC LIMIT $1 OFFSET $2`
- if err = o.db.SelectContext(ctx, &fwds, sql, limit, offset); err != nil {
+ if err = o.ds.SelectContext(ctx, &fwds, sql, limit, offset); err != nil {
return
}
return
}
// FindForwardersByChain returns all forwarder addresses for a chain.
-func (o *DbORM) FindForwardersByChain(ctx context.Context, evmChainId big.Big) (fwds []Forwarder, err error) {
+func (o *DSORM) FindForwardersByChain(ctx context.Context, evmChainId big.Big) (fwds []Forwarder, err error) {
sql := `SELECT * FROM evm.forwarders where evm_chain_id = $1 ORDER BY created_at DESC, id DESC`
- err = o.db.SelectContext(ctx, &fwds, sql, evmChainId)
+ err = o.ds.SelectContext(ctx, &fwds, sql, evmChainId)
return
}
-func (o *DbORM) FindForwardersInListByChain(ctx context.Context, evmChainId big.Big, addrs []common.Address) ([]Forwarder, error) {
+func (o *DSORM) FindForwardersInListByChain(ctx context.Context, evmChainId big.Big, addrs []common.Address) ([]Forwarder, error) {
var fwdrs []Forwarder
arg := map[string]interface{}{
@@ -127,8 +127,8 @@ func (o *DbORM) FindForwardersInListByChain(ctx context.Context, evmChainId big.
return nil, pkgerrors.Wrap(err, "Failed to run sqlx.IN on query")
}
- query = o.db.Rebind(query)
- err = o.db.SelectContext(ctx, &fwdrs, query, args...)
+ query = o.ds.Rebind(query)
+ err = o.ds.SelectContext(ctx, &fwdrs, query, args...)
if err != nil {
return nil, pkgerrors.Wrap(err, "Failed to execute query")
diff --git a/core/chains/evm/forwarders/orm_test.go b/core/chains/evm/forwarders/orm_test.go
index 7af55896b16..cd91428b021 100644
--- a/core/chains/evm/forwarders/orm_test.go
+++ b/core/chains/evm/forwarders/orm_test.go
@@ -16,26 +16,10 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
)
-type TestORM struct {
- ORM
- db sqlutil.DataSource
-}
-
-func setupORM(t *testing.T) *TestORM {
- t.Helper()
-
- var (
- db = pgtest.NewSqlxDB(t)
- orm = NewORM(db)
- )
-
- return &TestORM{ORM: orm, db: db}
-}
-
// Tests the atomicity of cleanup function passed to DeleteForwarder, during DELETE operation
func Test_DeleteForwarder(t *testing.T) {
t.Parallel()
- orm := setupORM(t)
+ orm := NewORM(pgtest.NewSqlxDB(t))
addr := testutils.NewAddress()
chainID := testutils.FixtureChainID
ctx := testutils.Context(t)
diff --git a/core/chains/evm/gas/arbitrum_estimator.go b/core/chains/evm/gas/arbitrum_estimator.go
index 40366c5b998..0cd4bbcdd0b 100644
--- a/core/chains/evm/gas/arbitrum_estimator.go
+++ b/core/chains/evm/gas/arbitrum_estimator.go
@@ -3,14 +3,10 @@ package gas
import (
"context"
"fmt"
- "math"
- "math/big"
"slices"
"sync"
"time"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
pkgerrors "github.com/pkg/errors"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
@@ -19,7 +15,7 @@ import (
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
- evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
)
type ArbConfig interface {
@@ -28,11 +24,6 @@ type ArbConfig interface {
BumpMin() *assets.Wei
}
-//go:generate mockery --quiet --name ethClient --output ./mocks/ --case=underscore --structname ETHClient
-type ethClient interface {
- CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
-}
-
// arbitrumEstimator is an Estimator which extends SuggestedPriceEstimator to use getPricesInArbGas() for gas limit estimation.
type arbitrumEstimator struct {
services.StateMachine
@@ -40,7 +31,6 @@ type arbitrumEstimator struct {
EvmEstimator // *SuggestedPriceEstimator
- client ethClient
pollPeriod time.Duration
logger logger.Logger
@@ -52,20 +42,23 @@ type arbitrumEstimator struct {
chInitialised chan struct{}
chStop services.StopChan
chDone chan struct{}
+
+ l1Oracle rollups.ArbL1GasOracle
}
-func NewArbitrumEstimator(lggr logger.Logger, cfg ArbConfig, rpcClient rpcClient, ethClient ethClient) EvmEstimator {
+func NewArbitrumEstimator(lggr logger.Logger, cfg ArbConfig, ethClient feeEstimatorClient, l1Oracle rollups.ArbL1GasOracle) EvmEstimator {
lggr = logger.Named(lggr, "ArbitrumEstimator")
+
return &arbitrumEstimator{
cfg: cfg,
- EvmEstimator: NewSuggestedPriceEstimator(lggr, rpcClient, cfg),
- client: ethClient,
+ EvmEstimator: NewSuggestedPriceEstimator(lggr, ethClient, cfg, l1Oracle),
pollPeriod: 10 * time.Second,
logger: lggr,
chForceRefetch: make(chan (chan struct{})),
chInitialised: make(chan struct{}),
chStop: make(chan struct{}),
chDone: make(chan struct{}),
+ l1Oracle: l1Oracle,
}
}
@@ -196,7 +189,7 @@ func (a *arbitrumEstimator) run() {
func (a *arbitrumEstimator) refreshPricesInArbGas() (t *time.Timer) {
t = time.NewTimer(utils.WithJitter(a.pollPeriod))
- perL2Tx, perL1CalldataUnit, err := a.callGetPricesInArbGas()
+ perL2Tx, perL1CalldataUnit, err := a.l1Oracle.GetPricesInArbGas()
if err != nil {
a.logger.Warnw("Failed to refresh prices", "err", err)
return
@@ -210,54 +203,3 @@ func (a *arbitrumEstimator) refreshPricesInArbGas() (t *time.Timer) {
a.getPricesInArbGasMu.Unlock()
return
}
-
-const (
- // ArbGasInfoAddress is the address of the "Precompiled contract that exists in every Arbitrum chain."
- // https://github.com/OffchainLabs/nitro/blob/f7645453cfc77bf3e3644ea1ac031eff629df325/contracts/src/precompiles/ArbGasInfo.sol
- ArbGasInfoAddress = "0x000000000000000000000000000000000000006C"
- // ArbGasInfo_getPricesInArbGas is the a hex encoded call to:
- // `function getPricesInArbGas() external view returns (uint256, uint256, uint256);`
- ArbGasInfo_getPricesInArbGas = "02199f34"
-)
-
-// callGetPricesInArbGas calls ArbGasInfo.getPricesInArbGas() on the precompile contract ArbGasInfoAddress.
-//
-// @return (per L2 tx, per L1 calldata unit, per storage allocation)
-// function getPricesInArbGas() external view returns (uint256, uint256, uint256);
-//
-// https://github.com/OffchainLabs/nitro/blob/f7645453cfc77bf3e3644ea1ac031eff629df325/contracts/src/precompiles/ArbGasInfo.sol#L69
-func (a *arbitrumEstimator) callGetPricesInArbGas() (perL2Tx uint32, perL1CalldataUnit uint32, err error) {
- ctx, cancel := a.chStop.CtxCancel(evmclient.ContextWithDefaultTimeout())
- defer cancel()
-
- precompile := common.HexToAddress(ArbGasInfoAddress)
- b, err := a.client.CallContract(ctx, ethereum.CallMsg{
- To: &precompile,
- Data: common.Hex2Bytes(ArbGasInfo_getPricesInArbGas),
- }, big.NewInt(-1))
- if err != nil {
- return 0, 0, err
- }
-
- if len(b) != 3*32 { // returns (uint256, uint256, uint256);
- err = fmt.Errorf("return data length (%d) different than expected (%d)", len(b), 3*32)
- return
- }
- bPerL2Tx := new(big.Int).SetBytes(b[:32])
- bPerL1CalldataUnit := new(big.Int).SetBytes(b[32:64])
- // ignore perStorageAllocation
- if !bPerL2Tx.IsUint64() || !bPerL1CalldataUnit.IsUint64() {
- err = fmt.Errorf("returned integers are not uint64 (%s, %s)", bPerL2Tx.String(), bPerL1CalldataUnit.String())
- return
- }
-
- perL2TxU64 := bPerL2Tx.Uint64()
- perL1CalldataUnitU64 := bPerL1CalldataUnit.Uint64()
- if perL2TxU64 > math.MaxUint32 || perL1CalldataUnitU64 > math.MaxUint32 {
- err = fmt.Errorf("returned integers are not uint32 (%d, %d)", perL2TxU64, perL1CalldataUnitU64)
- return
- }
- perL2Tx = uint32(perL2TxU64)
- perL1CalldataUnit = uint32(perL1CalldataUnitU64)
- return
-}
diff --git a/core/chains/evm/gas/arbitrum_estimator_test.go b/core/chains/evm/gas/arbitrum_estimator_test.go
index 3c46b466e87..54d7fc333e3 100644
--- a/core/chains/evm/gas/arbitrum_estimator_test.go
+++ b/core/chains/evm/gas/arbitrum_estimator_test.go
@@ -19,6 +19,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
)
@@ -52,9 +53,10 @@ func TestArbitrumEstimator(t *testing.T) {
var bumpMin = assets.NewWei(big.NewInt(1))
t.Run("calling GetLegacyGas on unstarted estimator returns error", func(t *testing.T) {
- rpcClient := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, rpcClient, ethClient)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
+
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
_, _, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
assert.EqualError(t, err, "estimator is not started")
})
@@ -64,21 +66,22 @@ func TestArbitrumEstimator(t *testing.T) {
zeros.Write(common.BigToHash(big.NewInt(0)).Bytes())
zeros.Write(common.BigToHash(big.NewInt(123455)).Bytes())
t.Run("calling GetLegacyGas on started estimator returns estimates", func(t *testing.T) {
- rpcClient := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- rpcClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(42)
})
- ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
- assert.Equal(t, gas.ArbGasInfoAddress, callMsg.To.String())
- assert.Equal(t, gas.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
+ assert.Equal(t, rollups.ArbGasInfoAddress, callMsg.To.String())
+ assert.Equal(t, rollups.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
assert.Equal(t, big.NewInt(-1), blockNumber)
}).Return(zeros.Bytes(), nil)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, rpcClient, ethClient)
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, feeEstimatorClient, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
require.NoError(t, err)
@@ -88,19 +91,20 @@ func TestArbitrumEstimator(t *testing.T) {
})
t.Run("gas price is lower than user specified max gas price", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, client, ethClient)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
+
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(42)
})
- ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
- assert.Equal(t, gas.ArbGasInfoAddress, callMsg.To.String())
- assert.Equal(t, gas.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
+ assert.Equal(t, rollups.ArbGasInfoAddress, callMsg.To.String())
+ assert.Equal(t, rollups.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
assert.Equal(t, big.NewInt(-1), blockNumber)
}).Return(zeros.Bytes(), nil)
@@ -113,19 +117,20 @@ func TestArbitrumEstimator(t *testing.T) {
})
t.Run("gas price is lower than global max gas price", func(t *testing.T) {
- ethClient := mocks.NewETHClient(t)
- client := mocks.NewRPCClient(t)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, client, ethClient)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(120)
})
- ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
- assert.Equal(t, gas.ArbGasInfoAddress, callMsg.To.String())
- assert.Equal(t, gas.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
+ assert.Equal(t, rollups.ArbGasInfoAddress, callMsg.To.String())
+ assert.Equal(t, rollups.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
assert.Equal(t, big.NewInt(-1), blockNumber)
}).Return(zeros.Bytes(), nil)
@@ -137,24 +142,26 @@ func TestArbitrumEstimator(t *testing.T) {
})
t.Run("calling BumpLegacyGas on unstarted arbitrum estimator returns error", func(t *testing.T) {
- rpcClient := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, rpcClient, ethClient)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
+
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
_, _, err := o.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(42), gasLimit, assets.NewWeiI(10), nil)
assert.EqualError(t, err, "estimator is not started")
})
t.Run("calling GetLegacyGas on started estimator if initial call failed returns error", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, client, ethClient)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(pkgerrors.New("kaboom"))
- ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(pkgerrors.New("kaboom"))
+ feeEstimatorClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
- assert.Equal(t, gas.ArbGasInfoAddress, callMsg.To.String())
- assert.Equal(t, gas.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
+ assert.Equal(t, rollups.ArbGasInfoAddress, callMsg.To.String())
+ assert.Equal(t, rollups.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
assert.Equal(t, big.NewInt(-1), blockNumber)
}).Return(zeros.Bytes(), nil)
@@ -165,17 +172,19 @@ func TestArbitrumEstimator(t *testing.T) {
})
t.Run("calling GetDynamicFee always returns error", func(t *testing.T) {
- rpcClient := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, rpcClient, ethClient)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
+
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
_, err := o.GetDynamicFee(testutils.Context(t), maxGasPrice)
assert.EqualError(t, err, "dynamic fees are not implemented for this estimator")
})
t.Run("calling BumpDynamicFee always returns error", func(t *testing.T) {
- rpcClient := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, rpcClient, ethClient)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
+
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{}, feeEstimatorClient, l1Oracle)
fee := gas.DynamicFee{
FeeCap: assets.NewWeiI(42),
TipCap: assets.NewWeiI(5),
@@ -185,9 +194,10 @@ func TestArbitrumEstimator(t *testing.T) {
})
t.Run("limit computes", func(t *testing.T) {
- rpcClient := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- rpcClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(42)
})
@@ -201,15 +211,15 @@ func TestArbitrumEstimator(t *testing.T) {
b.Write(common.BigToHash(big.NewInt(perL2Tx)).Bytes())
b.Write(common.BigToHash(big.NewInt(perL1Calldata)).Bytes())
b.Write(common.BigToHash(big.NewInt(123455)).Bytes())
- ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
- assert.Equal(t, gas.ArbGasInfoAddress, callMsg.To.String())
- assert.Equal(t, gas.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
+ assert.Equal(t, rollups.ArbGasInfoAddress, callMsg.To.String())
+ assert.Equal(t, rollups.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
assert.Equal(t, big.NewInt(-1), blockNumber)
}).Return(b.Bytes(), nil)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, rpcClient, ethClient)
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, feeEstimatorClient, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
require.NoError(t, err)
@@ -220,9 +230,10 @@ func TestArbitrumEstimator(t *testing.T) {
})
t.Run("limit exceeds max", func(t *testing.T) {
- rpcClient := mocks.NewRPCClient(t)
- ethClient := mocks.NewETHClient(t)
- rpcClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollups.NewArbitrumL1GasOracle(logger.Test(t), feeEstimatorClient)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(42)
})
@@ -235,15 +246,15 @@ func TestArbitrumEstimator(t *testing.T) {
b.Write(common.BigToHash(big.NewInt(perL2Tx)).Bytes())
b.Write(common.BigToHash(big.NewInt(perL1Calldata)).Bytes())
b.Write(common.BigToHash(big.NewInt(123455)).Bytes())
- ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
- assert.Equal(t, gas.ArbGasInfoAddress, callMsg.To.String())
- assert.Equal(t, gas.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
+ assert.Equal(t, rollups.ArbGasInfoAddress, callMsg.To.String())
+ assert.Equal(t, rollups.ArbGasInfo_getPricesInArbGas, fmt.Sprintf("%x", callMsg.Data))
assert.Equal(t, big.NewInt(-1), blockNumber)
}).Return(b.Bytes(), nil)
- o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, rpcClient, ethClient)
+ o := gas.NewArbitrumEstimator(logger.Test(t), &arbConfig{v: maxGasLimit, bumpPercent: bumpPercent, bumpMin: bumpMin}, feeEstimatorClient, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
require.Error(t, err, "expected error but got (%s, %d)", gasPrice, chainSpecificGasLimit)
diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go
index 5fb9c5d7173..8b8c626f725 100644
--- a/core/chains/evm/gas/block_history_estimator.go
+++ b/core/chains/evm/gas/block_history_estimator.go
@@ -24,7 +24,7 @@ import (
commonfee "github.com/smartcontractkit/chainlink/v2/common/fee"
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
- evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
@@ -97,7 +97,7 @@ type estimatorGasEstimatorConfig interface {
//go:generate mockery --quiet --name Config --output ./mocks/ --case=underscore
type BlockHistoryEstimator struct {
services.StateMachine
- ethClient evmclient.Client
+ ethClient feeEstimatorClient
chainID big.Int
config chainConfig
eConfig estimatorGasEstimatorConfig
@@ -120,13 +120,16 @@ type BlockHistoryEstimator struct {
initialFetch atomic.Bool
logger logger.SugaredLogger
+
+ l1Oracle rollups.L1Oracle
}
// NewBlockHistoryEstimator returns a new BlockHistoryEstimator that listens
// for new heads and updates the base gas price dynamically based on the
// configured percentile of gas prices in that block
-func NewBlockHistoryEstimator(lggr logger.Logger, ethClient evmclient.Client, cfg chainConfig, eCfg estimatorGasEstimatorConfig, bhCfg BlockHistoryConfig, chainID big.Int) EvmEstimator {
+func NewBlockHistoryEstimator(lggr logger.Logger, ethClient feeEstimatorClient, cfg chainConfig, eCfg estimatorGasEstimatorConfig, bhCfg BlockHistoryConfig, chainID big.Int, l1Oracle rollups.L1Oracle) EvmEstimator {
ctx, cancel := context.WithCancel(context.Background())
+
b := &BlockHistoryEstimator{
ethClient: ethClient,
chainID: chainID,
@@ -141,6 +144,7 @@ func NewBlockHistoryEstimator(lggr logger.Logger, ethClient evmclient.Client, cf
ctx: ctx,
ctxCancel: cancel,
logger: logger.Sugared(logger.Named(lggr, "BlockHistoryEstimator")),
+ l1Oracle: l1Oracle,
}
return b
@@ -230,6 +234,10 @@ func (b *BlockHistoryEstimator) Start(ctx context.Context) error {
})
}
+func (b *BlockHistoryEstimator) L1Oracle() rollups.L1Oracle {
+ return b.l1Oracle
+}
+
func (b *BlockHistoryEstimator) Close() error {
return b.StopOnce("BlockHistoryEstimator", func() error {
b.ctxCancel()
diff --git a/core/chains/evm/gas/block_history_estimator_test.go b/core/chains/evm/gas/block_history_estimator_test.go
index 5260a22bff3..941b60545ba 100644
--- a/core/chains/evm/gas/block_history_estimator_test.go
+++ b/core/chains/evm/gas/block_history_estimator_test.go
@@ -24,6 +24,8 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
+ rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
@@ -42,12 +44,12 @@ func newBlockHistoryConfig() *gas.MockBlockHistoryConfig {
return c
}
-func newBlockHistoryEstimatorWithChainID(t *testing.T, c evmclient.Client, cfg gas.Config, gCfg gas.GasEstimatorConfig, bhCfg gas.BlockHistoryConfig, cid big.Int) gas.EvmEstimator {
- return gas.NewBlockHistoryEstimator(logger.Test(t), c, cfg, gCfg, bhCfg, cid)
+func newBlockHistoryEstimatorWithChainID(t *testing.T, c evmclient.Client, cfg gas.Config, gCfg gas.GasEstimatorConfig, bhCfg gas.BlockHistoryConfig, cid big.Int, l1Oracle rollups.L1Oracle) gas.EvmEstimator {
+ return gas.NewBlockHistoryEstimator(logger.Test(t), c, cfg, gCfg, bhCfg, cid, l1Oracle)
}
-func newBlockHistoryEstimator(t *testing.T, c evmclient.Client, cfg gas.Config, gCfg gas.GasEstimatorConfig, bhCfg gas.BlockHistoryConfig) *gas.BlockHistoryEstimator {
- iface := newBlockHistoryEstimatorWithChainID(t, c, cfg, gCfg, bhCfg, cltest.FixtureChainID)
+func newBlockHistoryEstimator(t *testing.T, c evmclient.Client, cfg gas.Config, gCfg gas.GasEstimatorConfig, bhCfg gas.BlockHistoryConfig, l1Oracle rollups.L1Oracle) *gas.BlockHistoryEstimator {
+ iface := newBlockHistoryEstimatorWithChainID(t, c, cfg, gCfg, bhCfg, cltest.FixtureChainID, l1Oracle)
return gas.BlockHistoryEstimatorFromInterface(iface)
}
@@ -77,8 +79,9 @@ func TestBlockHistoryEstimator_Start(t *testing.T) {
t.Run("loads initial state", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
h := &evmtypes.Head{Hash: utils.NewHash(), Number: 42, BaseFeePerGas: assets.NewWeiI(420)}
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil)
@@ -121,8 +124,9 @@ func TestBlockHistoryEstimator_Start(t *testing.T) {
cfg2 := gas.NewMockConfig()
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg2, geCfg2, bhCfg2)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg2, geCfg2, bhCfg2, l1Oracle)
h := &evmtypes.Head{Hash: utils.NewHash(), Number: 42, BaseFeePerGas: assets.NewWeiI(420)}
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil)
@@ -154,8 +158,9 @@ func TestBlockHistoryEstimator_Start(t *testing.T) {
t.Run("boots even if initial batch call returns nothing", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
h := &evmtypes.Head{Hash: utils.NewHash(), Number: 42}
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil)
@@ -172,8 +177,9 @@ func TestBlockHistoryEstimator_Start(t *testing.T) {
t.Run("starts anyway if fetching latest head fails", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(nil, pkgerrors.New("something exploded"))
@@ -193,8 +199,9 @@ func TestBlockHistoryEstimator_Start(t *testing.T) {
t.Run("starts anyway if fetching first fetch fails, but errors on estimation", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
h := &evmtypes.Head{Hash: utils.NewHash(), Number: 42, BaseFeePerGas: assets.NewWeiI(420)}
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil)
@@ -216,8 +223,9 @@ func TestBlockHistoryEstimator_Start(t *testing.T) {
t.Run("returns error if main context is cancelled", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
h := &evmtypes.Head{Hash: utils.NewHash(), Number: 42, BaseFeePerGas: assets.NewWeiI(420)}
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil)
@@ -232,8 +240,9 @@ func TestBlockHistoryEstimator_Start(t *testing.T) {
t.Run("starts anyway even if the fetch context is cancelled due to taking longer than the MaxStartTime", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
h := &evmtypes.Head{Hash: utils.NewHash(), Number: 42, BaseFeePerGas: assets.NewWeiI(420)}
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil)
@@ -261,8 +270,9 @@ func TestBlockHistoryEstimator_OnNewLongestChain(t *testing.T) {
bhCfg := newBlockHistoryConfig()
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = false
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg, l1Oracle)
assert.Nil(t, gas.GetLatestBaseFee(bhe))
@@ -284,6 +294,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
t.Run("with history size of 0, errors", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -295,7 +307,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
head := cltest.Head(42)
err := bhe.FetchBlocks(testutils.Context(t), head)
@@ -305,6 +317,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
t.Run("with current block height less than block delay does nothing", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
var blockDelay uint16 = 3
@@ -315,7 +329,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
for i := -1; i < 3; i++ {
head := cltest.Head(i)
@@ -327,6 +341,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
t.Run("with error retrieving blocks returns error", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
var blockDelay uint16 = 3
@@ -338,7 +354,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
ethClient.On("BatchCallContext", mock.Anything, mock.Anything).Return(pkgerrors.New("something exploded"))
@@ -349,6 +365,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
t.Run("batch fetches heads and transactions and sets them on the block history estimator instance", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
var blockDelay uint16
@@ -362,7 +380,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b41 := evmtypes.Block{
Number: 41,
@@ -443,6 +461,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
t.Run("does not refetch blocks below EVM.FinalityDepth", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
var blockDelay uint16
@@ -455,7 +475,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b0 := evmtypes.Block{
Number: 0,
@@ -506,6 +526,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
t.Run("replaces blocks on re-org within EVM.FinalityDepth", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
var blockDelay uint16
@@ -518,7 +540,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b0 := evmtypes.Block{
Number: 0,
@@ -577,6 +599,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
t.Run("uses locally cached blocks if they are in the chain", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
var blockDelay uint16
var historySize uint16 = 3
@@ -589,7 +613,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b0 := evmtypes.Block{
Number: 0,
@@ -634,6 +658,8 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
t.Run("fetches max(BlockHistoryEstimatorCheckInclusionBlocks, BlockHistoryEstimatorBlockHistorySize)", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
var blockDelay uint16
var historySize uint16 = 1
@@ -648,7 +674,7 @@ func TestBlockHistoryEstimator_FetchBlocks(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b42 := evmtypes.Block{
Number: 42,
@@ -686,6 +712,8 @@ func TestBlockHistoryEstimator_FetchBlocksAndRecalculate_NoEIP1559(t *testing.T)
t.Parallel()
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
bhCfg.BlockDelayF = uint16(0)
@@ -698,7 +726,7 @@ func TestBlockHistoryEstimator_FetchBlocksAndRecalculate_NoEIP1559(t *testing.T)
geCfg.PriceMaxF = assets.NewWeiI(1000)
geCfg.PriceMinF = assets.NewWeiI(0)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b1 := evmtypes.Block{
Number: 1,
@@ -744,6 +772,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
t.Run("does not crash or set gas price to zero if there are no transactions", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -753,7 +782,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = false
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
blocks := []evmtypes.Block{}
gas.SetRollingBlockHistory(bhe, blocks)
@@ -770,6 +799,8 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
t.Run("sets gas price to EVM.GasEstimator.PriceMax if the calculation would otherwise exceed it", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -780,7 +811,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
geCfg.PriceMaxF = maxGasPrice
geCfg.PriceMinF = minGasPrice
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
blocks := []evmtypes.Block{
{
@@ -805,6 +836,8 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
t.Run("sets gas price to EVM.GasEstimator.PriceMin if the calculation would otherwise fall below it", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -815,7 +848,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
geCfg.PriceMaxF = maxGasPrice
geCfg.PriceMinF = minGasPrice
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
blocks := []evmtypes.Block{
{
@@ -840,6 +873,8 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
t.Run("ignores any transaction with a zero gas limit", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -850,7 +885,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
geCfg.PriceMaxF = maxGasPrice
geCfg.PriceMinF = minGasPrice
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b1Hash := utils.NewHash()
b2Hash := utils.NewHash()
@@ -887,6 +922,8 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
t.Run("takes into account zero priced transactions if chain is not Gnosis", func(t *testing.T) {
// Because everyone loves free gas!
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -897,7 +934,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
geCfg.PriceMaxF = maxGasPrice
geCfg.PriceMinF = assets.NewWeiI(0)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b1Hash := utils.NewHash()
@@ -920,6 +957,8 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
t.Run("ignores zero priced transactions only on Gnosis", func(t *testing.T) {
ethClient := evmtest.NewEthClientMock(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -930,7 +969,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
geCfg.PriceMaxF = maxGasPrice
geCfg.PriceMinF = assets.NewWeiI(11) // Has to be set as Gnosis will only ignore transactions below this price
- ibhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ ibhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
bhe := gas.BlockHistoryEstimatorFromInterface(ibhe)
b1Hash := utils.NewHash()
@@ -964,6 +1003,8 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
// Seems unlikely we will ever experience gas prices > 9 Petawei on mainnet (praying to the eth Gods 🙏)
// But other chains could easily use a different base of account
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -976,7 +1017,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
geCfg.PriceMaxF = reasonablyHugeGasPrice
geCfg.PriceMinF = assets.NewWeiI(10)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
unreasonablyHugeGasPrice := assets.NewWeiI(1000000).Mul(big.NewInt(math.MaxInt64))
@@ -1011,6 +1052,8 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
t.Run("doesn't panic if gas price is nil (although I'm still unsure how this can happen)", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -1021,7 +1064,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) {
geCfg.PriceMaxF = maxGasPrice
geCfg.PriceMinF = assets.NewWeiI(100)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b1Hash := utils.NewHash()
@@ -1057,6 +1100,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
t.Run("does not crash or set gas price to zero if there are no transactions", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -1066,7 +1110,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
blocks := []evmtypes.Block{}
gas.SetRollingBlockHistory(bhe, blocks)
@@ -1095,6 +1139,8 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
t.Run("does not set tip higher than EVM.GasEstimator.PriceMax", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -1106,7 +1152,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
geCfg.PriceMinF = assets.NewWeiI(0)
geCfg.TipCapMinF = assets.NewWeiI(0)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
blocks := []evmtypes.Block{
{
@@ -1133,6 +1179,8 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
t.Run("sets tip cap to EVM.GasEstimator.TipCapMin if the calculation would otherwise fall below it", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -1144,7 +1192,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
geCfg.PriceMinF = assets.NewWeiI(0)
geCfg.TipCapMinF = assets.NewWeiI(10)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
blocks := []evmtypes.Block{
{
@@ -1171,6 +1219,8 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
t.Run("ignores any transaction with a zero gas limit", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -1182,7 +1232,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
geCfg.PriceMinF = assets.NewWeiI(0)
geCfg.TipCapMinF = assets.NewWeiI(10)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b1Hash := utils.NewHash()
b2Hash := utils.NewHash()
@@ -1219,6 +1269,8 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
t.Run("respects minimum gas tip cap", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -1230,7 +1282,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
geCfg.PriceMinF = assets.NewWeiI(0)
geCfg.TipCapMinF = assets.NewWeiI(1)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b1Hash := utils.NewHash()
@@ -1255,6 +1307,8 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
t.Run("allows to set zero tip cap if minimum allows it", func(t *testing.T) {
// Because everyone loves *cheap* gas!
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -1266,7 +1320,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
geCfg.PriceMinF = assets.NewWeiI(0)
geCfg.TipCapMinF = assets.NewWeiI(0)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
b1Hash := utils.NewHash()
@@ -1291,12 +1345,14 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) {
func TestBlockHistoryEstimator_IsUsable(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
block := evmtypes.Block{
Number: 0,
Hash: utils.NewHash(),
@@ -1373,13 +1429,15 @@ func TestBlockHistoryEstimator_IsUsable(t *testing.T) {
func TestBlockHistoryEstimator_EffectiveTipCap(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = true
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
block := evmtypes.Block{
Number: 0,
@@ -1433,13 +1491,15 @@ func TestBlockHistoryEstimator_EffectiveTipCap(t *testing.T) {
func TestBlockHistoryEstimator_EffectiveGasPrice(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = false
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
block := evmtypes.Block{
Number: 0,
@@ -1772,6 +1832,7 @@ func TestBlockHistoryEstimator_EIP1559Block_Unmarshal(t *testing.T) {
func TestBlockHistoryEstimator_GetLegacyGas(t *testing.T) {
t.Parallel()
+ l1Oracle := rollupMocks.NewL1Oracle(t)
cfg := gas.NewMockConfig()
bhCfg := newBlockHistoryConfig()
@@ -1786,7 +1847,7 @@ func TestBlockHistoryEstimator_GetLegacyGas(t *testing.T) {
geCfg.PriceMaxF = maxGasPrice
geCfg.PriceMinF = assets.NewWeiI(0)
- bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg, l1Oracle)
blocks := []evmtypes.Block{
{
@@ -1830,7 +1891,7 @@ func TestBlockHistoryEstimator_GetLegacyGas(t *testing.T) {
geCfg.EIP1559DynamicFeesF = false
- bhe = newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg)
+ bhe = newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg, l1Oracle)
gas.SetRollingBlockHistory(bhe, blocks)
bhe.Recalculate(cltest.Head(1))
gas.SimulateStart(t, bhe)
@@ -1867,7 +1928,9 @@ func TestBlockHistoryEstimator_UseDefaultPriceAsFallback(t *testing.T) {
geCfg.PriceDefaultF = assets.NewWeiI(100)
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
h := &evmtypes.Head{Hash: utils.NewHash(), Number: 42, BaseFeePerGas: nil}
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil)
@@ -1918,7 +1981,9 @@ func TestBlockHistoryEstimator_UseDefaultPriceAsFallback(t *testing.T) {
geCfg.BumpThresholdF = uint64(1)
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg, l1Oracle)
h := &evmtypes.Head{Hash: utils.NewHash(), Number: 42, BaseFeePerGas: assets.NewWeiI(40)}
ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(h, nil)
@@ -1967,7 +2032,9 @@ func TestBlockHistoryEstimator_GetDynamicFee(t *testing.T) {
geCfg.TipCapMinF = assets.NewWeiI(0)
geCfg.PriceMinF = assets.NewWeiI(0)
- bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg, l1Oracle)
blocks := []evmtypes.Block{
{
@@ -2065,9 +2132,10 @@ func TestBlockHistoryEstimator_CheckConnectivity(t *testing.T) {
lggr, obs := logger.TestObserved(t, zapcore.DebugLevel)
geCfg := &gas.MockGasEstimatorConfig{}
geCfg.EIP1559DynamicFeesF = false
+ l1Oracle := rollupMocks.NewL1Oracle(t)
bhe := gas.BlockHistoryEstimatorFromInterface(
- gas.NewBlockHistoryEstimator(lggr, nil, cfg, geCfg, bhCfg, *testutils.NewRandomEVMChainID()),
+ gas.NewBlockHistoryEstimator(lggr, nil, cfg, geCfg, bhCfg, *testutils.NewRandomEVMChainID(), l1Oracle),
)
attempts := []gas.EvmPriorAttempt{
@@ -2365,8 +2433,9 @@ func TestBlockHistoryEstimator_Bumps(t *testing.T) {
geCfg.BumpPercentF = 10
geCfg.BumpMinF = assets.NewWeiI(150)
geCfg.PriceMaxF = maxGasPrice
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg, l1Oracle)
b1 := evmtypes.Block{
Number: 1,
@@ -2394,8 +2463,9 @@ func TestBlockHistoryEstimator_Bumps(t *testing.T) {
geCfg.BumpPercentF = 10
geCfg.BumpMinF = assets.NewWeiI(150)
geCfg.PriceMaxF = maxGasPrice
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg, l1Oracle)
t.Run("ignores nil current gas price", func(t *testing.T) {
gasPrice, gasLimit, err := bhe.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(42), 100000, maxGasPrice, nil)
@@ -2475,8 +2545,9 @@ func TestBlockHistoryEstimator_Bumps(t *testing.T) {
geCfg.BumpPercentF = 10
geCfg.BumpMinF = assets.NewWeiI(150)
geCfg.PriceMaxF = maxGasPrice
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg, l1Oracle)
b1 := evmtypes.Block{
BaseFeePerGas: assets.NewWeiI(1),
@@ -2508,8 +2579,9 @@ func TestBlockHistoryEstimator_Bumps(t *testing.T) {
geCfg.BumpMinF = assets.NewWeiI(150)
geCfg.PriceMaxF = maxGasPrice
geCfg.TipCapDefaultF = assets.NewWeiI(52)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg)
+ bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg, l1Oracle)
t.Run("when current tip cap is nil", func(t *testing.T) {
originalFee := gas.DynamicFee{FeeCap: assets.NewWeiI(100), TipCap: assets.NewWeiI(25)}
diff --git a/core/chains/evm/gas/cmd/arbgas/main.go b/core/chains/evm/gas/cmd/arbgas/main.go
deleted file mode 100644
index dc107a50b52..00000000000
--- a/core/chains/evm/gas/cmd/arbgas/main.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// arbgas takes a single URL argument and prints the result of three GetLegacyGas calls to the Arbitrum gas estimator.
-package main
-
-import (
- "context"
- "fmt"
- "log"
- "os"
-
- "github.com/ethereum/go-ethereum/ethclient"
- "github.com/ethereum/go-ethereum/rpc"
-
- "github.com/smartcontractkit/chainlink-common/pkg/logger"
- feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
-)
-
-func main() {
- if l := len(os.Args); l != 2 {
- log.Fatal("Expected one URL argument but got", l-1)
- }
- url := os.Args[1]
- lggr, err := logger.New()
- if err != nil {
- log.Fatal("Failed to create logger:", err)
- }
-
- ctx := context.Background()
- withEstimator(ctx, logger.Sugared(lggr), url, func(e gas.EvmEstimator) {
- printGetLegacyGas(ctx, e, make([]byte, 10), 500_000, assets.GWei(1))
- printGetLegacyGas(ctx, e, make([]byte, 10), 500_000, assets.GWei(1), feetypes.OptForceRefetch)
- printGetLegacyGas(ctx, e, make([]byte, 10), max, assets.GWei(1))
- })
-}
-
-func printGetLegacyGas(ctx context.Context, e gas.EvmEstimator, calldata []byte, l2GasLimit uint64, maxGasPrice *assets.Wei, opts ...feetypes.Opt) {
- price, limit, err := e.GetLegacyGas(ctx, calldata, l2GasLimit, maxGasPrice, opts...)
- if err != nil {
- log.Println("failed to get legacy gas:", err)
- return
- }
- fmt.Println("Price:", price)
- fmt.Println("Limit:", limit)
-}
-
-const max = 50_000_000
-
-func withEstimator(ctx context.Context, lggr logger.SugaredLogger, url string, f func(e gas.EvmEstimator)) {
- rc, err := rpc.Dial(url)
- if err != nil {
- log.Fatal(err)
- }
- ec := ethclient.NewClient(rc)
- e := gas.NewArbitrumEstimator(lggr, &config{max: max}, rc, ec)
- ctx, cancel := context.WithCancel(ctx)
- defer cancel()
- err = e.Start(ctx)
- if err != nil {
- log.Fatal(err)
- }
- defer lggr.ErrorIfFn(e.Close, "Error closing ArbitrumEstimator")
-
- f(e)
-}
-
-var _ gas.ArbConfig = &config{}
-
-type config struct {
- max uint64
- bumpPercent uint16
- bumpMin *assets.Wei
-}
-
-func (c *config) LimitMax() uint64 {
- return c.max
-}
-
-func (c *config) BumpPercent() uint16 {
- return c.bumpPercent
-}
-
-func (c *config) BumpMin() *assets.Wei {
- return c.bumpMin
-}
diff --git a/core/chains/evm/gas/fixed_price_estimator.go b/core/chains/evm/gas/fixed_price_estimator.go
index fc65413d375..f4749b093a1 100644
--- a/core/chains/evm/gas/fixed_price_estimator.go
+++ b/core/chains/evm/gas/fixed_price_estimator.go
@@ -9,6 +9,7 @@ import (
commonfee "github.com/smartcontractkit/chainlink/v2/common/fee"
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
@@ -18,6 +19,7 @@ type fixedPriceEstimator struct {
config fixedPriceEstimatorConfig
bhConfig fixedPriceEstimatorBlockHistoryConfig
lggr logger.SugaredLogger
+ l1Oracle rollups.L1Oracle
}
type bumpConfig interface {
LimitMultiplier() float32
@@ -43,8 +45,8 @@ type fixedPriceEstimatorBlockHistoryConfig interface {
// NewFixedPriceEstimator returns a new "FixedPrice" estimator which will
// always use the config default values for gas prices and limits
-func NewFixedPriceEstimator(cfg fixedPriceEstimatorConfig, bhCfg fixedPriceEstimatorBlockHistoryConfig, lggr logger.Logger) EvmEstimator {
- return &fixedPriceEstimator{cfg, bhCfg, logger.Sugared(logger.Named(lggr, "FixedPriceEstimator"))}
+func NewFixedPriceEstimator(cfg fixedPriceEstimatorConfig, ethClient feeEstimatorClient, bhCfg fixedPriceEstimatorBlockHistoryConfig, lggr logger.Logger, l1Oracle rollups.L1Oracle) EvmEstimator {
+ return &fixedPriceEstimator{cfg, bhCfg, logger.Sugared(logger.Named(lggr, "FixedPriceEstimator")), l1Oracle}
}
func (f *fixedPriceEstimator) Start(context.Context) error {
@@ -128,6 +130,10 @@ func (f *fixedPriceEstimator) BumpDynamicFee(
)
}
+func (f *fixedPriceEstimator) L1Oracle() rollups.L1Oracle {
+ return f.l1Oracle
+}
+
func (f *fixedPriceEstimator) Name() string { return f.lggr.Name() }
func (f *fixedPriceEstimator) Ready() error { return nil }
func (f *fixedPriceEstimator) HealthReport() map[string]error { return map[string]error{} }
diff --git a/core/chains/evm/gas/fixed_price_estimator_test.go b/core/chains/evm/gas/fixed_price_estimator_test.go
index c31bd41aeee..9c68f9d2fbc 100644
--- a/core/chains/evm/gas/fixed_price_estimator_test.go
+++ b/core/chains/evm/gas/fixed_price_estimator_test.go
@@ -9,6 +9,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
+ rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
)
@@ -26,7 +27,9 @@ func Test_FixedPriceEstimator(t *testing.T) {
t.Run("GetLegacyGas returns EvmGasPriceDefault from config", func(t *testing.T) {
config := &gas.MockGasEstimatorConfig{}
- f := gas.NewFixedPriceEstimator(config, &blockHistoryConfig{}, logger.Test(t))
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ f := gas.NewFixedPriceEstimator(config, nil, &blockHistoryConfig{}, logger.Test(t), l1Oracle)
config.PriceDefaultF = assets.NewWeiI(42)
config.PriceMaxF = maxGasPrice
@@ -41,7 +44,9 @@ func Test_FixedPriceEstimator(t *testing.T) {
config := &gas.MockGasEstimatorConfig{}
config.PriceDefaultF = assets.NewWeiI(42)
config.PriceMaxF = assets.NewWeiI(35)
- f := gas.NewFixedPriceEstimator(config, &blockHistoryConfig{}, logger.Test(t))
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ f := gas.NewFixedPriceEstimator(config, nil, &blockHistoryConfig{}, logger.Test(t), l1Oracle)
gasPrice, gasLimit, err := f.GetLegacyGas(testutils.Context(t), nil, 100000, assets.NewWeiI(30))
require.NoError(t, err)
@@ -53,8 +58,9 @@ func Test_FixedPriceEstimator(t *testing.T) {
config := &gas.MockGasEstimatorConfig{}
config.PriceDefaultF = assets.NewWeiI(42)
config.PriceMaxF = assets.NewWeiI(20)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- f := gas.NewFixedPriceEstimator(config, &blockHistoryConfig{}, logger.Test(t))
+ f := gas.NewFixedPriceEstimator(config, nil, &blockHistoryConfig{}, logger.Test(t), l1Oracle)
gasPrice, gasLimit, err := f.GetLegacyGas(testutils.Context(t), nil, 100000, assets.NewWeiI(30))
require.NoError(t, err)
assert.Equal(t, 100000, int(gasLimit))
@@ -67,9 +73,10 @@ func Test_FixedPriceEstimator(t *testing.T) {
config.PriceMaxF = maxGasPrice
config.BumpPercentF = uint16(10)
config.BumpMinF = assets.NewWeiI(150)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
lggr := logger.TestSugared(t)
- f := gas.NewFixedPriceEstimator(config, &blockHistoryConfig{}, lggr)
+ f := gas.NewFixedPriceEstimator(config, nil, &blockHistoryConfig{}, lggr, l1Oracle)
gasPrice, gasLimit, err := f.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(42), 100000, maxGasPrice, nil)
require.NoError(t, err)
@@ -87,9 +94,10 @@ func Test_FixedPriceEstimator(t *testing.T) {
config.TipCapDefaultF = assets.NewWeiI(52)
config.FeeCapDefaultF = assets.NewWeiI(100)
config.BumpThresholdF = uint64(3)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
lggr := logger.Test(t)
- f := gas.NewFixedPriceEstimator(config, &blockHistoryConfig{}, lggr)
+ f := gas.NewFixedPriceEstimator(config, nil, &blockHistoryConfig{}, lggr, l1Oracle)
fee, err := f.GetDynamicFee(testutils.Context(t), maxGasPrice)
require.NoError(t, err)
@@ -120,9 +128,10 @@ func Test_FixedPriceEstimator(t *testing.T) {
config.TipCapDefaultF = assets.NewWeiI(52)
config.BumpMinF = assets.NewWeiI(150)
config.BumpPercentF = uint16(10)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
lggr := logger.TestSugared(t)
- f := gas.NewFixedPriceEstimator(config, &blockHistoryConfig{}, lggr)
+ f := gas.NewFixedPriceEstimator(config, nil, &blockHistoryConfig{}, lggr, l1Oracle)
originalFee := gas.DynamicFee{FeeCap: assets.NewWeiI(100), TipCap: assets.NewWeiI(25)}
fee, err := f.BumpDynamicFee(testutils.Context(t), originalFee, maxGasPrice, nil)
diff --git a/core/chains/evm/gas/mocks/eth_client.go b/core/chains/evm/gas/mocks/eth_client.go
deleted file mode 100644
index bb0784f8515..00000000000
--- a/core/chains/evm/gas/mocks/eth_client.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Code generated by mockery v2.38.0. DO NOT EDIT.
-
-package mocks
-
-import (
- context "context"
- big "math/big"
-
- ethereum "github.com/ethereum/go-ethereum"
-
- mock "github.com/stretchr/testify/mock"
-)
-
-// ETHClient is an autogenerated mock type for the ethClient type
-type ETHClient struct {
- mock.Mock
-}
-
-// CallContract provides a mock function with given fields: ctx, msg, blockNumber
-func (_m *ETHClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
- ret := _m.Called(ctx, msg, blockNumber)
-
- if len(ret) == 0 {
- panic("no return value specified for CallContract")
- }
-
- var r0 []byte
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) ([]byte, error)); ok {
- return rf(ctx, msg, blockNumber)
- }
- if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) []byte); ok {
- r0 = rf(ctx, msg, blockNumber)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]byte)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg, *big.Int) error); ok {
- r1 = rf(ctx, msg, blockNumber)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// NewETHClient creates a new instance of ETHClient. 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 NewETHClient(t interface {
- mock.TestingT
- Cleanup(func())
-}) *ETHClient {
- mock := ÐClient{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/core/chains/evm/gas/mocks/evm_estimator.go b/core/chains/evm/gas/mocks/evm_estimator.go
index a0b6fa62432..600e43a7c69 100644
--- a/core/chains/evm/gas/mocks/evm_estimator.go
+++ b/core/chains/evm/gas/mocks/evm_estimator.go
@@ -13,6 +13,8 @@ import (
mock "github.com/stretchr/testify/mock"
+ rollups "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
+
types "github.com/smartcontractkit/chainlink/v2/common/fee/types"
)
@@ -196,6 +198,26 @@ func (_m *EvmEstimator) HealthReport() map[string]error {
return r0
}
+// L1Oracle provides a mock function with given fields:
+func (_m *EvmEstimator) L1Oracle() rollups.L1Oracle {
+ ret := _m.Called()
+
+ if len(ret) == 0 {
+ panic("no return value specified for L1Oracle")
+ }
+
+ var r0 rollups.L1Oracle
+ if rf, ok := ret.Get(0).(func() rollups.L1Oracle); ok {
+ r0 = rf()
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(rollups.L1Oracle)
+ }
+ }
+
+ return r0
+}
+
// Name provides a mock function with given fields:
func (_m *EvmEstimator) Name() string {
ret := _m.Called()
diff --git a/core/chains/evm/gas/mocks/fee_estimator_client.go b/core/chains/evm/gas/mocks/fee_estimator_client.go
new file mode 100644
index 00000000000..50eb17d2dac
--- /dev/null
+++ b/core/chains/evm/gas/mocks/fee_estimator_client.go
@@ -0,0 +1,154 @@
+// Code generated by mockery v2.38.0. DO NOT EDIT.
+
+package mocks
+
+import (
+ context "context"
+ big "math/big"
+
+ ethereum "github.com/ethereum/go-ethereum"
+
+ mock "github.com/stretchr/testify/mock"
+
+ rpc "github.com/ethereum/go-ethereum/rpc"
+
+ types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+)
+
+// FeeEstimatorClient is an autogenerated mock type for the feeEstimatorClient type
+type FeeEstimatorClient struct {
+ mock.Mock
+}
+
+// BatchCallContext provides a mock function with given fields: ctx, b
+func (_m *FeeEstimatorClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error {
+ ret := _m.Called(ctx, b)
+
+ if len(ret) == 0 {
+ panic("no return value specified for BatchCallContext")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(context.Context, []rpc.BatchElem) error); ok {
+ r0 = rf(ctx, b)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// CallContext provides a mock function with given fields: ctx, result, method, args
+func (_m *FeeEstimatorClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
+ var _ca []interface{}
+ _ca = append(_ca, ctx, result, method)
+ _ca = append(_ca, args...)
+ ret := _m.Called(_ca...)
+
+ if len(ret) == 0 {
+ panic("no return value specified for CallContext")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(context.Context, interface{}, string, ...interface{}) error); ok {
+ r0 = rf(ctx, result, method, args...)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// CallContract provides a mock function with given fields: ctx, msg, blockNumber
+func (_m *FeeEstimatorClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
+ ret := _m.Called(ctx, msg, blockNumber)
+
+ if len(ret) == 0 {
+ panic("no return value specified for CallContract")
+ }
+
+ var r0 []byte
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) ([]byte, error)); ok {
+ return rf(ctx, msg, blockNumber)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) []byte); ok {
+ r0 = rf(ctx, msg, blockNumber)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).([]byte)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg, *big.Int) error); ok {
+ r1 = rf(ctx, msg, blockNumber)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// ConfiguredChainID provides a mock function with given fields:
+func (_m *FeeEstimatorClient) ConfiguredChainID() *big.Int {
+ ret := _m.Called()
+
+ if len(ret) == 0 {
+ panic("no return value specified for ConfiguredChainID")
+ }
+
+ var r0 *big.Int
+ if rf, ok := ret.Get(0).(func() *big.Int); ok {
+ r0 = rf()
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*big.Int)
+ }
+ }
+
+ return r0
+}
+
+// HeadByNumber provides a mock function with given fields: ctx, n
+func (_m *FeeEstimatorClient) HeadByNumber(ctx context.Context, n *big.Int) (*types.Head, error) {
+ ret := _m.Called(ctx, n)
+
+ if len(ret) == 0 {
+ panic("no return value specified for HeadByNumber")
+ }
+
+ var r0 *types.Head
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, *big.Int) (*types.Head, error)); ok {
+ return rf(ctx, n)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, *big.Int) *types.Head); ok {
+ r0 = rf(ctx, n)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*types.Head)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, *big.Int) error); ok {
+ r1 = rf(ctx, n)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// NewFeeEstimatorClient creates a new instance of FeeEstimatorClient. 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 NewFeeEstimatorClient(t interface {
+ mock.TestingT
+ Cleanup(func())
+}) *FeeEstimatorClient {
+ mock := &FeeEstimatorClient{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/core/chains/evm/gas/mocks/rpc_client.go b/core/chains/evm/gas/mocks/rpc_client.go
deleted file mode 100644
index d1262665f66..00000000000
--- a/core/chains/evm/gas/mocks/rpc_client.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Code generated by mockery v2.38.0. DO NOT EDIT.
-
-package mocks
-
-import (
- context "context"
-
- mock "github.com/stretchr/testify/mock"
-)
-
-// RPCClient is an autogenerated mock type for the rpcClient type
-type RPCClient struct {
- mock.Mock
-}
-
-// CallContext provides a mock function with given fields: ctx, result, method, args
-func (_m *RPCClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
- var _ca []interface{}
- _ca = append(_ca, ctx, result, method)
- _ca = append(_ca, args...)
- ret := _m.Called(_ca...)
-
- if len(ret) == 0 {
- panic("no return value specified for CallContext")
- }
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, interface{}, string, ...interface{}) error); ok {
- r0 = rf(ctx, result, method, args...)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// NewRPCClient creates a new instance of RPCClient. 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 NewRPCClient(t interface {
- mock.TestingT
- Cleanup(func())
-}) *RPCClient {
- mock := &RPCClient{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go
index 17ee6f6d405..c50e19373f1 100644
--- a/core/chains/evm/gas/models.go
+++ b/core/chains/evm/gas/models.go
@@ -5,8 +5,10 @@ import (
"fmt"
"math/big"
+ "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/rpc"
pkgerrors "github.com/pkg/errors"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
@@ -16,9 +18,8 @@ import (
"github.com/smartcontractkit/chainlink/v2/common/config"
commonfee "github.com/smartcontractkit/chainlink/v2/common/fee"
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
- commontypes "github.com/smartcontractkit/chainlink/v2/common/types"
+ "github.com/smartcontractkit/chainlink/v2/common/headtracker"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
- evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/label"
@@ -30,7 +31,7 @@ import (
//go:generate mockery --quiet --name EvmFeeEstimator --output ./mocks/ --case=underscore
type EvmFeeEstimator interface {
services.Service
- commontypes.HeadTrackable[*evmtypes.Head, common.Hash]
+ headtracker.HeadTrackable[*evmtypes.Head, common.Hash]
// L1Oracle returns the L1 gas price oracle only if the chain has one, e.g. OP stack L2s and Arbitrum.
L1Oracle() rollups.L1Oracle
@@ -41,8 +42,17 @@ type EvmFeeEstimator interface {
GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error)
}
+//go:generate mockery --quiet --name feeEstimatorClient --output ./mocks/ --case=underscore --structname FeeEstimatorClient
+type feeEstimatorClient interface {
+ CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
+ BatchCallContext(ctx context.Context, b []rpc.BatchElem) error
+ CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
+ ConfiguredChainID() *big.Int
+ HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error)
+}
+
// NewEstimator returns the estimator for a given config
-func NewEstimator(lggr logger.Logger, ethClient evmclient.Client, cfg Config, geCfg evmconfig.GasEstimator) EvmFeeEstimator {
+func NewEstimator(lggr logger.Logger, ethClient feeEstimatorClient, cfg Config, geCfg evmconfig.GasEstimator) EvmFeeEstimator {
bh := geCfg.BlockHistory()
s := geCfg.Mode()
lggr.Infow(fmt.Sprintf("Initializing EVM gas estimator in mode: %s", s),
@@ -75,27 +85,27 @@ func NewEstimator(lggr logger.Logger, ethClient evmclient.Client, cfg Config, ge
switch s {
case "Arbitrum":
newEstimator = func(l logger.Logger) EvmEstimator {
- return NewArbitrumEstimator(lggr, geCfg, ethClient, ethClient)
+ return NewArbitrumEstimator(lggr, geCfg, ethClient, rollups.NewArbitrumL1GasOracle(lggr, ethClient))
}
case "BlockHistory":
newEstimator = func(l logger.Logger) EvmEstimator {
- return NewBlockHistoryEstimator(lggr, ethClient, cfg, geCfg, bh, *ethClient.ConfiguredChainID())
+ return NewBlockHistoryEstimator(lggr, ethClient, cfg, geCfg, bh, *ethClient.ConfiguredChainID(), l1Oracle)
}
case "FixedPrice":
newEstimator = func(l logger.Logger) EvmEstimator {
- return NewFixedPriceEstimator(geCfg, bh, lggr)
+ return NewFixedPriceEstimator(geCfg, ethClient, bh, lggr, l1Oracle)
}
case "L2Suggested", "SuggestedPrice":
newEstimator = func(l logger.Logger) EvmEstimator {
- return NewSuggestedPriceEstimator(lggr, ethClient, geCfg)
+ return NewSuggestedPriceEstimator(lggr, ethClient, geCfg, l1Oracle)
}
default:
lggr.Warnf("GasEstimator: unrecognised mode '%s', falling back to FixedPriceEstimator", s)
newEstimator = func(l logger.Logger) EvmEstimator {
- return NewFixedPriceEstimator(geCfg, bh, lggr)
+ return NewFixedPriceEstimator(geCfg, ethClient, bh, lggr, l1Oracle)
}
}
- return NewWrappedEvmEstimator(lggr, newEstimator, df, l1Oracle, geCfg)
+ return NewEvmFeeEstimator(lggr, newEstimator, df, geCfg)
}
// DynamicFee encompasses both FeeCap and TipCap for EIP1559 transactions
@@ -117,7 +127,7 @@ type EvmPriorAttempt struct {
//
//go:generate mockery --quiet --name EvmEstimator --output ./mocks/ --case=underscore
type EvmEstimator interface {
- commontypes.HeadTrackable[*evmtypes.Head, common.Hash]
+ headtracker.HeadTrackable[*evmtypes.Head, common.Hash]
services.Service
// GetLegacyGas Calculates initial gas fee for non-EIP1559 transaction
@@ -138,6 +148,8 @@ type EvmEstimator interface {
// - be sorted in order from highest price to lowest price
// - all be of transaction type 0x2
BumpDynamicFee(ctx context.Context, original DynamicFee, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, err error)
+
+ L1Oracle() rollups.L1Oracle
}
var _ feetypes.Fee = (*EvmFee)(nil)
@@ -159,53 +171,53 @@ func (fee EvmFee) ValidDynamic() bool {
return fee.DynamicFeeCap != nil && fee.DynamicTipCap != nil
}
-// WrappedEvmEstimator provides a struct that wraps the EVM specific dynamic and legacy estimators into one estimator that conforms to the generic FeeEstimator
-type WrappedEvmEstimator struct {
+// evmFeeEstimator provides a struct that wraps the EVM specific dynamic and legacy estimators into one estimator that conforms to the generic FeeEstimator
+type evmFeeEstimator struct {
services.StateMachine
lggr logger.Logger
EvmEstimator
EIP1559Enabled bool
- l1Oracle rollups.L1Oracle
geCfg GasEstimatorConfig
}
-var _ EvmFeeEstimator = (*WrappedEvmEstimator)(nil)
+var _ EvmFeeEstimator = (*evmFeeEstimator)(nil)
-func NewWrappedEvmEstimator(lggr logger.Logger, newEstimator func(logger.Logger) EvmEstimator, eip1559Enabled bool, l1Oracle rollups.L1Oracle, geCfg GasEstimatorConfig) EvmFeeEstimator {
+func NewEvmFeeEstimator(lggr logger.Logger, newEstimator func(logger.Logger) EvmEstimator, eip1559Enabled bool, geCfg GasEstimatorConfig) EvmFeeEstimator {
lggr = logger.Named(lggr, "WrappedEvmEstimator")
- return &WrappedEvmEstimator{
+ return &evmFeeEstimator{
lggr: lggr,
EvmEstimator: newEstimator(lggr),
EIP1559Enabled: eip1559Enabled,
- l1Oracle: l1Oracle,
geCfg: geCfg,
}
}
-func (e *WrappedEvmEstimator) Name() string {
+func (e *evmFeeEstimator) Name() string {
return e.lggr.Name()
}
-func (e *WrappedEvmEstimator) Start(ctx context.Context) error {
+func (e *evmFeeEstimator) Start(ctx context.Context) error {
return e.StartOnce(e.Name(), func() error {
if err := e.EvmEstimator.Start(ctx); err != nil {
return pkgerrors.Wrap(err, "failed to start EVMEstimator")
}
- if e.l1Oracle != nil {
- if err := e.l1Oracle.Start(ctx); err != nil {
+ l1Oracle := e.L1Oracle()
+ if l1Oracle != nil {
+ if err := l1Oracle.Start(ctx); err != nil {
return pkgerrors.Wrap(err, "failed to start L1Oracle")
}
}
return nil
})
}
-func (e *WrappedEvmEstimator) Close() error {
+func (e *evmFeeEstimator) Close() error {
return e.StopOnce(e.Name(), func() error {
var errEVM, errOracle error
errEVM = pkgerrors.Wrap(e.EvmEstimator.Close(), "failed to stop EVMEstimator")
- if e.l1Oracle != nil {
- errOracle = pkgerrors.Wrap(e.l1Oracle.Close(), "failed to stop L1Oracle")
+ l1Oracle := e.L1Oracle()
+ if l1Oracle != nil {
+ errOracle = pkgerrors.Wrap(l1Oracle.Close(), "failed to stop L1Oracle")
}
if errEVM != nil {
@@ -215,12 +227,13 @@ func (e *WrappedEvmEstimator) Close() error {
})
}
-func (e *WrappedEvmEstimator) Ready() error {
+func (e *evmFeeEstimator) Ready() error {
var errEVM, errOracle error
errEVM = e.EvmEstimator.Ready()
- if e.l1Oracle != nil {
- errOracle = e.l1Oracle.Ready()
+ l1Oracle := e.L1Oracle()
+ if l1Oracle != nil {
+ errOracle = l1Oracle.Ready()
}
if errEVM != nil {
@@ -229,21 +242,23 @@ func (e *WrappedEvmEstimator) Ready() error {
return errOracle
}
-func (e *WrappedEvmEstimator) HealthReport() map[string]error {
+func (e *evmFeeEstimator) HealthReport() map[string]error {
report := map[string]error{e.Name(): e.Healthy()}
services.CopyHealth(report, e.EvmEstimator.HealthReport())
- if e.l1Oracle != nil {
- services.CopyHealth(report, e.l1Oracle.HealthReport())
+
+ l1Oracle := e.L1Oracle()
+ if l1Oracle != nil {
+ services.CopyHealth(report, l1Oracle.HealthReport())
}
return report
}
-func (e *WrappedEvmEstimator) L1Oracle() rollups.L1Oracle {
- return e.l1Oracle
+func (e *evmFeeEstimator) L1Oracle() rollups.L1Oracle {
+ return e.EvmEstimator.L1Oracle()
}
-func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint64, err error) {
+func (e *evmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint64, err error) {
// get dynamic fee
if e.EIP1559Enabled {
var dynamicFee DynamicFee
@@ -267,7 +282,7 @@ func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLi
return
}
-func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) {
+func (e *evmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) {
fees, gasLimit, err := e.GetFee(ctx, calldata, feeLimit, maxFeePrice, opts...)
if err != nil {
return nil, err
@@ -285,7 +300,7 @@ func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth,
return amountWithFees, nil
}
-func (e *WrappedEvmEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint64, err error) {
+func (e *evmFeeEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint64, err error) {
// validate only 1 fee type is present
if (!originalFee.ValidDynamic() && originalFee.Legacy == nil) || (originalFee.ValidDynamic() && originalFee.Legacy != nil) {
err = pkgerrors.New("only one dynamic or legacy fee can be defined")
diff --git a/core/chains/evm/gas/models_test.go b/core/chains/evm/gas/models_test.go
index ec9542b4040..722beb8021a 100644
--- a/core/chains/evm/gas/models_test.go
+++ b/core/chains/evm/gas/models_test.go
@@ -10,9 +10,11 @@ import (
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
+ "github.com/smartcontractkit/chainlink/v2/common/config"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
)
@@ -49,14 +51,24 @@ func TestWrappedEvmEstimator(t *testing.T) {
// L1Oracle returns the correct L1Oracle interface
t.Run("L1Oracle", func(t *testing.T) {
lggr := logger.Test(t)
+
+ evmEstimator := mocks.NewEvmEstimator(t)
+ evmEstimator.On("L1Oracle").Return(nil).Once()
+
+ getEst := func(logger.Logger) gas.EvmEstimator { return evmEstimator }
+
// expect nil
- estimator := gas.NewWrappedEvmEstimator(lggr, getRootEst, false, nil, nil)
+ estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, nil)
l1Oracle := estimator.L1Oracle()
+
assert.Nil(t, l1Oracle)
// expect l1Oracle
- oracle := rollupMocks.NewL1Oracle(t)
- estimator = gas.NewWrappedEvmEstimator(lggr, getRootEst, false, oracle, geCfg)
+ oracle := rollups.NewL1GasOracle(lggr, nil, config.ChainOptimismBedrock)
+ // cast oracle to L1Oracle interface
+ estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg)
+
+ evmEstimator.On("L1Oracle").Return(oracle).Once()
l1Oracle = estimator.L1Oracle()
assert.Equal(t, oracle, l1Oracle)
})
@@ -66,7 +78,7 @@ func TestWrappedEvmEstimator(t *testing.T) {
lggr := logger.Test(t)
// expect legacy fee data
dynamicFees := false
- estimator := gas.NewWrappedEvmEstimator(lggr, getRootEst, dynamicFees, nil, geCfg)
+ estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg)
fee, max, err := estimator.GetFee(ctx, nil, 0, nil)
require.NoError(t, err)
assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), max)
@@ -76,7 +88,7 @@ func TestWrappedEvmEstimator(t *testing.T) {
// expect dynamic fee data
dynamicFees = true
- estimator = gas.NewWrappedEvmEstimator(lggr, getRootEst, dynamicFees, nil, geCfg)
+ estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg)
fee, max, err = estimator.GetFee(ctx, nil, gasLimit, nil)
require.NoError(t, err)
assert.Equal(t, uint64(float32(gasLimit)*limitMultiplier), max)
@@ -89,7 +101,7 @@ func TestWrappedEvmEstimator(t *testing.T) {
t.Run("BumpFee", func(t *testing.T) {
lggr := logger.Test(t)
dynamicFees := false
- estimator := gas.NewWrappedEvmEstimator(lggr, getRootEst, dynamicFees, nil, geCfg)
+ estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg)
// expect legacy fee data
fee, max, err := estimator.BumpFee(ctx, gas.EvmFee{Legacy: assets.NewWeiI(0)}, 0, nil, nil)
@@ -127,7 +139,7 @@ func TestWrappedEvmEstimator(t *testing.T) {
// expect legacy fee data
dynamicFees := false
- estimator := gas.NewWrappedEvmEstimator(lggr, getRootEst, dynamicFees, nil, geCfg)
+ estimator := gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg)
total, err := estimator.GetMaxCost(ctx, val, nil, gasLimit, nil)
require.NoError(t, err)
fee := new(big.Int).Mul(legacyFee.ToInt(), big.NewInt(int64(gasLimit)))
@@ -136,7 +148,7 @@ func TestWrappedEvmEstimator(t *testing.T) {
// expect dynamic fee data
dynamicFees = true
- estimator = gas.NewWrappedEvmEstimator(lggr, getRootEst, dynamicFees, nil, geCfg)
+ estimator = gas.NewEvmFeeEstimator(lggr, getRootEst, dynamicFees, geCfg)
total, err = estimator.GetMaxCost(ctx, val, nil, gasLimit, nil)
require.NoError(t, err)
fee = new(big.Int).Mul(dynamicFee.FeeCap.ToInt(), big.NewInt(int64(gasLimit)))
@@ -147,13 +159,12 @@ func TestWrappedEvmEstimator(t *testing.T) {
t.Run("Name", func(t *testing.T) {
lggr := logger.Test(t)
- oracle := rollupMocks.NewL1Oracle(t)
evmEstimator := mocks.NewEvmEstimator(t)
evmEstimator.On("Name").Return(mockEvmEstimatorName, nil).Once()
- estimator := gas.NewWrappedEvmEstimator(lggr, func(logger.Logger) gas.EvmEstimator {
+ estimator := gas.NewEvmFeeEstimator(lggr, func(logger.Logger) gas.EvmEstimator {
return evmEstimator
- }, false, oracle, geCfg)
+ }, false, geCfg)
require.Equal(t, mockEstimatorName, estimator.Name())
require.Equal(t, mockEvmEstimatorName, evmEstimator.Name())
@@ -170,13 +181,17 @@ func TestWrappedEvmEstimator(t *testing.T) {
oracle.On("Close").Return(nil).Once()
getEst := func(logger.Logger) gas.EvmEstimator { return evmEstimator }
- estimator := gas.NewWrappedEvmEstimator(lggr, getEst, false, nil, geCfg)
+ evmEstimator.On("L1Oracle", mock.Anything).Return(nil).Twice()
+
+ estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg)
err := estimator.Start(ctx)
require.NoError(t, err)
err = estimator.Close()
require.NoError(t, err)
- estimator = gas.NewWrappedEvmEstimator(lggr, getEst, false, oracle, geCfg)
+ evmEstimator.On("L1Oracle", mock.Anything).Return(oracle).Twice()
+
+ estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg)
err = estimator.Start(ctx)
require.NoError(t, err)
err = estimator.Close()
@@ -188,15 +203,16 @@ func TestWrappedEvmEstimator(t *testing.T) {
evmEstimator := mocks.NewEvmEstimator(t)
oracle := rollupMocks.NewL1Oracle(t)
+ evmEstimator.On("L1Oracle").Return(oracle).Twice()
evmEstimator.On("Ready").Return(nil).Twice()
- oracle.On("Ready").Return(nil).Once()
+ oracle.On("Ready").Return(nil).Twice()
getEst := func(logger.Logger) gas.EvmEstimator { return evmEstimator }
- estimator := gas.NewWrappedEvmEstimator(lggr, getEst, false, nil, geCfg)
+ estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg)
err := estimator.Ready()
require.NoError(t, err)
- estimator = gas.NewWrappedEvmEstimator(lggr, getEst, false, oracle, geCfg)
+ estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg)
err = estimator.Ready()
require.NoError(t, err)
})
@@ -211,17 +227,21 @@ func TestWrappedEvmEstimator(t *testing.T) {
oracleKey := "oracle"
oracleError := pkgerrors.New("oracle error")
+ evmEstimator.On("L1Oracle").Return(nil).Once()
evmEstimator.On("HealthReport").Return(map[string]error{evmEstimatorKey: evmEstimatorError}).Twice()
+
oracle.On("HealthReport").Return(map[string]error{oracleKey: oracleError}).Once()
getEst := func(logger.Logger) gas.EvmEstimator { return evmEstimator }
- estimator := gas.NewWrappedEvmEstimator(lggr, getEst, false, nil, geCfg)
+ estimator := gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg)
report := estimator.HealthReport()
require.True(t, pkgerrors.Is(report[evmEstimatorKey], evmEstimatorError))
require.Nil(t, report[oracleKey])
require.NotNil(t, report[mockEstimatorName])
- estimator = gas.NewWrappedEvmEstimator(lggr, getEst, false, oracle, geCfg)
+ evmEstimator.On("L1Oracle").Return(oracle).Once()
+
+ estimator = gas.NewEvmFeeEstimator(lggr, getEst, false, geCfg)
report = estimator.HealthReport()
require.True(t, pkgerrors.Is(report[evmEstimatorKey], evmEstimatorError))
require.True(t, pkgerrors.Is(report[oracleKey], oracleError))
diff --git a/core/chains/evm/gas/rollups/arbitrum_l1_oracle.go b/core/chains/evm/gas/rollups/arbitrum_l1_oracle.go
new file mode 100644
index 00000000000..d0b4c5808ad
--- /dev/null
+++ b/core/chains/evm/gas/rollups/arbitrum_l1_oracle.go
@@ -0,0 +1,300 @@
+package rollups
+
+import (
+ "context"
+ "fmt"
+ "math"
+ "math/big"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/logger"
+ "github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/utils"
+
+ gethtypes "github.com/ethereum/go-ethereum/core/types"
+
+ "github.com/smartcontractkit/chainlink/v2/common/client"
+ "github.com/smartcontractkit/chainlink/v2/common/config"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
+ evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+)
+
+type ArbL1GasOracle interface {
+ L1Oracle
+ GetPricesInArbGas() (perL2Tx uint32, perL1CalldataUnit uint32, err error)
+}
+
+// Reads L2-specific precompiles and caches the l1GasPrice set by the L2.
+type arbitrumL1Oracle struct {
+ services.StateMachine
+ client l1OracleClient
+ pollPeriod time.Duration
+ logger logger.SugaredLogger
+ chainType config.ChainType
+
+ l1GasPriceAddress string
+ gasPriceMethod string
+ l1GasPriceMethodAbi abi.ABI
+ l1GasPriceMu sync.RWMutex
+ l1GasPrice priceEntry
+
+ l1GasCostAddress string
+ gasCostMethod string
+ l1GasCostMethodAbi abi.ABI
+
+ chInitialised chan struct{}
+ chStop services.StopChan
+ chDone chan struct{}
+}
+
+const (
+ // ArbGasInfoAddress is the address of the "Precompiled contract that exists in every Arbitrum chain."
+ // https://github.com/OffchainLabs/nitro/blob/f7645453cfc77bf3e3644ea1ac031eff629df325/contracts/src/precompiles/ArbGasInfo.sol
+ ArbGasInfoAddress = "0x000000000000000000000000000000000000006C"
+ // ArbGasInfo_getL1BaseFeeEstimate is the a hex encoded call to:
+ // `function getL1BaseFeeEstimate() external view returns (uint256);`
+ ArbGasInfo_getL1BaseFeeEstimate = "getL1BaseFeeEstimate"
+ // NodeInterfaceAddress is the address of the precompiled contract that is only available through RPC
+ // https://github.com/OffchainLabs/nitro/blob/e815395d2e91fb17f4634cad72198f6de79c6e61/nodeInterface/NodeInterface.go#L37
+ ArbNodeInterfaceAddress = "0x00000000000000000000000000000000000000C8"
+ // ArbGasInfo_getPricesInArbGas is the a hex encoded call to:
+ // `function gasEstimateL1Component(address to, bool contractCreation, bytes calldata data) external payable returns (uint64 gasEstimateForL1, uint256 baseFee, uint256 l1BaseFeeEstimate);`
+ ArbNodeInterface_gasEstimateL1Component = "gasEstimateL1Component"
+ // ArbGasInfo_getPricesInArbGas is the a hex encoded call to:
+ // `function getPricesInArbGas() external view returns (uint256, uint256, uint256);`
+ ArbGasInfo_getPricesInArbGas = "02199f34"
+)
+
+func NewArbitrumL1GasOracle(lggr logger.Logger, ethClient l1OracleClient) *arbitrumL1Oracle {
+ var l1GasPriceAddress, gasPriceMethod, l1GasCostAddress, gasCostMethod string
+ var l1GasPriceMethodAbi, l1GasCostMethodAbi abi.ABI
+ var gasPriceErr, gasCostErr error
+
+ l1GasPriceAddress = ArbGasInfoAddress
+ gasPriceMethod = ArbGasInfo_getL1BaseFeeEstimate
+ l1GasPriceMethodAbi, gasPriceErr = abi.JSON(strings.NewReader(GetL1BaseFeeEstimateAbiString))
+ l1GasCostAddress = ArbNodeInterfaceAddress
+ gasCostMethod = ArbNodeInterface_gasEstimateL1Component
+ l1GasCostMethodAbi, gasCostErr = abi.JSON(strings.NewReader(GasEstimateL1ComponentAbiString))
+
+ if gasPriceErr != nil {
+ panic("Failed to parse L1 gas price method ABI for chain: arbitrum")
+ }
+ if gasCostErr != nil {
+ panic("Failed to parse L1 gas cost method ABI for chain: arbitrum")
+ }
+
+ return &arbitrumL1Oracle{
+ client: ethClient,
+ pollPeriod: PollPeriod,
+ logger: logger.Sugared(logger.Named(lggr, "L1GasOracle(arbitrum)")),
+ chainType: config.ChainArbitrum,
+
+ l1GasPriceAddress: l1GasPriceAddress,
+ gasPriceMethod: gasPriceMethod,
+ l1GasPriceMethodAbi: l1GasPriceMethodAbi,
+ l1GasCostAddress: l1GasCostAddress,
+ gasCostMethod: gasCostMethod,
+ l1GasCostMethodAbi: l1GasCostMethodAbi,
+
+ chInitialised: make(chan struct{}),
+ chStop: make(chan struct{}),
+ chDone: make(chan struct{}),
+ }
+}
+
+func (o *arbitrumL1Oracle) Name() string {
+ return o.logger.Name()
+}
+
+func (o *arbitrumL1Oracle) Start(ctx context.Context) error {
+ return o.StartOnce(o.Name(), func() error {
+ go o.run()
+ <-o.chInitialised
+ return nil
+ })
+}
+func (o *arbitrumL1Oracle) Close() error {
+ return o.StopOnce(o.Name(), func() error {
+ close(o.chStop)
+ <-o.chDone
+ return nil
+ })
+}
+
+func (o *arbitrumL1Oracle) HealthReport() map[string]error {
+ return map[string]error{o.Name(): o.Healthy()}
+}
+
+func (o *arbitrumL1Oracle) run() {
+ defer close(o.chDone)
+
+ t := o.refresh()
+ close(o.chInitialised)
+
+ for {
+ select {
+ case <-o.chStop:
+ return
+ case <-t.C:
+ t = o.refresh()
+ }
+ }
+}
+func (o *arbitrumL1Oracle) refresh() (t *time.Timer) {
+ t, err := o.refreshWithError()
+ if err != nil {
+ o.SvcErrBuffer.Append(err)
+ }
+ return
+}
+
+func (o *arbitrumL1Oracle) refreshWithError() (t *time.Timer, err error) {
+ t = time.NewTimer(utils.WithJitter(o.pollPeriod))
+
+ ctx, cancel := o.chStop.CtxCancel(evmclient.ContextWithDefaultTimeout())
+ defer cancel()
+
+ price, err := o.fetchL1GasPrice(ctx)
+ if err != nil {
+ return t, err
+ }
+
+ o.l1GasPriceMu.Lock()
+ defer o.l1GasPriceMu.Unlock()
+ o.l1GasPrice = priceEntry{price: assets.NewWei(price), timestamp: time.Now()}
+ return
+}
+
+func (o *arbitrumL1Oracle) fetchL1GasPrice(ctx context.Context) (price *big.Int, err error) {
+ var callData, b []byte
+ precompile := common.HexToAddress(o.l1GasPriceAddress)
+ callData, err = o.l1GasPriceMethodAbi.Pack(o.gasPriceMethod)
+ if err != nil {
+ errMsg := "failed to pack calldata for arbitrum L1 gas price method"
+ o.logger.Errorf(errMsg)
+ return nil, fmt.Errorf("%s: %w", errMsg, err)
+ }
+ b, err = o.client.CallContract(ctx, ethereum.CallMsg{
+ To: &precompile,
+ Data: callData,
+ }, nil)
+ if err != nil {
+ errMsg := "gas oracle contract call failed"
+ o.logger.Errorf(errMsg)
+ return nil, fmt.Errorf("%s: %w", errMsg, err)
+ }
+
+ if len(b) != 32 { // returns uint256;
+ errMsg := fmt.Sprintf("return data length (%d) different than expected (%d)", len(b), 32)
+ o.logger.Criticalf(errMsg)
+ return nil, fmt.Errorf(errMsg)
+ }
+ price = new(big.Int).SetBytes(b)
+ return price, nil
+}
+
+func (o *arbitrumL1Oracle) GasPrice(_ context.Context) (l1GasPrice *assets.Wei, err error) {
+ var timestamp time.Time
+ ok := o.IfStarted(func() {
+ o.l1GasPriceMu.RLock()
+ l1GasPrice = o.l1GasPrice.price
+ timestamp = o.l1GasPrice.timestamp
+ o.l1GasPriceMu.RUnlock()
+ })
+ if !ok {
+ return l1GasPrice, fmt.Errorf("L1GasOracle is not started; cannot estimate gas")
+ }
+ if l1GasPrice == nil {
+ return l1GasPrice, fmt.Errorf("failed to get l1 gas price; gas price not set")
+ }
+ // Validate the price has been updated within the pollPeriod * 2
+ // Allowing double the poll period before declaring the price stale to give ample time for the refresh to process
+ if time.Since(timestamp) > o.pollPeriod*2 {
+ return l1GasPrice, fmt.Errorf("gas price is stale")
+ }
+ return
+}
+
+// Gets the L1 gas cost for the provided transaction at the specified block num
+// If block num is not provided, the value on the latest block num is used
+func (o *arbitrumL1Oracle) GetGasCost(ctx context.Context, tx *gethtypes.Transaction, blockNum *big.Int) (*assets.Wei, error) {
+ ctx, cancel := context.WithTimeout(ctx, client.QueryTimeout)
+ defer cancel()
+ var callData, b []byte
+ var err error
+
+ if callData, err = o.l1GasCostMethodAbi.Pack(o.gasCostMethod, tx.To(), false, tx.Data()); err != nil {
+ return nil, fmt.Errorf("failed to pack calldata for %s L1 gas cost estimation method: %w", o.chainType, err)
+ }
+
+ precompile := common.HexToAddress(o.l1GasCostAddress)
+ b, err = o.client.CallContract(ctx, ethereum.CallMsg{
+ To: &precompile,
+ Data: callData,
+ }, blockNum)
+ if err != nil {
+ errorMsg := fmt.Sprintf("gas oracle contract call failed: %v", err)
+ o.logger.Errorf(errorMsg)
+ return nil, fmt.Errorf(errorMsg)
+ }
+
+ var l1GasCost *big.Int
+
+ if len(b) != 8+2*32 { // returns (uint64 gasEstimateForL1, uint256 baseFee, uint256 l1BaseFeeEstimate);
+ errorMsg := fmt.Sprintf("return data length (%d) different than expected (%d)", len(b), 8+2*32)
+ o.logger.Critical(errorMsg)
+ return nil, fmt.Errorf(errorMsg)
+ }
+ l1GasCost = new(big.Int).SetBytes(b[:8])
+
+ return assets.NewWei(l1GasCost), nil
+}
+
+// callGetPricesInArbGas calls ArbGasInfo.getPricesInArbGas() on the precompile contract ArbGasInfoAddress.
+//
+// @return (per L2 tx, per L1 calldata unit, per storage allocation)
+// function getPricesInArbGas() external view returns (uint256, uint256, uint256);
+//
+// https://github.com/OffchainLabs/nitro/blob/f7645453cfc77bf3e3644ea1ac031eff629df325/contracts/src/precompiles/ArbGasInfo.sol#L69
+
+func (o *arbitrumL1Oracle) GetPricesInArbGas() (perL2Tx uint32, perL1CalldataUnit uint32, err error) {
+ ctx, cancel := o.chStop.CtxCancel(evmclient.ContextWithDefaultTimeout())
+ defer cancel()
+ precompile := common.HexToAddress(ArbGasInfoAddress)
+ b, err := o.client.CallContract(ctx, ethereum.CallMsg{
+ To: &precompile,
+ Data: common.Hex2Bytes(ArbGasInfo_getPricesInArbGas),
+ }, big.NewInt(-1))
+ if err != nil {
+ return 0, 0, err
+ }
+
+ if len(b) != 3*32 { // returns (uint256, uint256, uint256);
+ err = fmt.Errorf("return data length (%d) different than expected (%d)", len(b), 3*32)
+ return
+ }
+ bPerL2Tx := new(big.Int).SetBytes(b[:32])
+ bPerL1CalldataUnit := new(big.Int).SetBytes(b[32:64])
+ // ignore perStorageAllocation
+ if !bPerL2Tx.IsUint64() || !bPerL1CalldataUnit.IsUint64() {
+ err = fmt.Errorf("returned integers are not uint64 (%s, %s)", bPerL2Tx.String(), bPerL1CalldataUnit.String())
+ return
+ }
+
+ perL2TxU64 := bPerL2Tx.Uint64()
+ perL1CalldataUnitU64 := bPerL1CalldataUnit.Uint64()
+ if perL2TxU64 > math.MaxUint32 || perL1CalldataUnitU64 > math.MaxUint32 {
+ err = fmt.Errorf("returned integers are not uint32 (%d, %d)", perL2TxU64, perL1CalldataUnitU64)
+ return
+ }
+ perL2Tx = uint32(perL2TxU64)
+ perL1CalldataUnit = uint32(perL1CalldataUnitU64)
+ return
+}
diff --git a/core/chains/evm/gas/rollups/l1_oracle.go b/core/chains/evm/gas/rollups/l1_oracle.go
index ae46071cf0d..05ceb720ab2 100644
--- a/core/chains/evm/gas/rollups/l1_oracle.go
+++ b/core/chains/evm/gas/rollups/l1_oracle.go
@@ -5,36 +5,35 @@ import (
"fmt"
"math/big"
"slices"
- "strings"
- "sync"
"time"
"github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc"
- "github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services"
- "github.com/smartcontractkit/chainlink-common/pkg/utils"
- gethtypes "github.com/ethereum/go-ethereum/core/types"
+ "github.com/smartcontractkit/chainlink-common/pkg/logger"
- "github.com/smartcontractkit/chainlink/v2/common/client"
"github.com/smartcontractkit/chainlink/v2/common/config"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
- evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
)
-//go:generate mockery --quiet --name ethClient --output ./mocks/ --case=underscore --structname ETHClient
-type ethClient interface {
- CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
- BatchCallContext(ctx context.Context, b []rpc.BatchElem) error
+// L1Oracle provides interface for fetching L1-specific fee components if the chain is an L2.
+// For example, on Optimistic Rollups, this oracle can return rollup-specific l1BaseFee
+//
+//go:generate mockery --quiet --name L1Oracle --output ./mocks/ --case=underscore
+type L1Oracle interface {
+ services.Service
+
+ GasPrice(ctx context.Context) (*assets.Wei, error)
+ GetGasCost(ctx context.Context, tx *types.Transaction, blockNum *big.Int) (*assets.Wei, error)
}
-//go:generate mockery --quiet --name daPriceReader --output ./mocks/ --case=underscore --structname DAPriceReader
-type daPriceReader interface {
- GetDAGasPrice(ctx context.Context) (*big.Int, error)
+//go:generate mockery --quiet --name l1OracleClient --output ./mocks/ --case=underscore --structname L1OracleClient
+type l1OracleClient interface {
+ CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
+ BatchCallContext(ctx context.Context, b []rpc.BatchElem) error
}
type priceEntry struct {
@@ -42,71 +41,7 @@ type priceEntry struct {
timestamp time.Time
}
-// Reads L2-specific precompiles and caches the l1GasPrice set by the L2.
-type l1Oracle struct {
- services.StateMachine
- client ethClient
- pollPeriod time.Duration
- logger logger.SugaredLogger
- chainType config.ChainType
-
- l1GasPriceAddress string
- gasPriceMethod string
- l1GasPriceMethodAbi abi.ABI
- l1GasPriceMu sync.RWMutex
- l1GasPrice priceEntry
-
- l1GasCostAddress string
- gasCostMethod string
- l1GasCostMethodAbi abi.ABI
-
- priceReader daPriceReader
-
- chInitialised chan struct{}
- chStop services.StopChan
- chDone chan struct{}
-}
-
const (
- // ArbGasInfoAddress is the address of the "Precompiled contract that exists in every Arbitrum chain."
- // https://github.com/OffchainLabs/nitro/blob/f7645453cfc77bf3e3644ea1ac031eff629df325/contracts/src/precompiles/ArbGasInfo.sol
- ArbGasInfoAddress = "0x000000000000000000000000000000000000006C"
- // ArbGasInfo_getL1BaseFeeEstimate is the a hex encoded call to:
- // `function getL1BaseFeeEstimate() external view returns (uint256);`
- ArbGasInfo_getL1BaseFeeEstimate = "getL1BaseFeeEstimate"
- // NodeInterfaceAddress is the address of the precompiled contract that is only available through RPC
- // https://github.com/OffchainLabs/nitro/blob/e815395d2e91fb17f4634cad72198f6de79c6e61/nodeInterface/NodeInterface.go#L37
- ArbNodeInterfaceAddress = "0x00000000000000000000000000000000000000C8"
- // ArbGasInfo_getPricesInArbGas is the a hex encoded call to:
- // `function gasEstimateL1Component(address to, bool contractCreation, bytes calldata data) external payable returns (uint64 gasEstimateForL1, uint256 baseFee, uint256 l1BaseFeeEstimate);`
- ArbNodeInterface_gasEstimateL1Component = "gasEstimateL1Component"
-
- // OPGasOracleAddress is the address of the precompiled contract that exists on OP stack chain.
- // This is the case for Optimism and Base.
- OPGasOracleAddress = "0x420000000000000000000000000000000000000F"
- // OPGasOracle_l1BaseFee is a hex encoded call to:
- // `function l1BaseFee() external view returns (uint256);`
- OPGasOracle_l1BaseFee = "l1BaseFee"
- // OPGasOracle_getL1Fee is a hex encoded call to:
- // `function getL1Fee(bytes) external view returns (uint256);`
- OPGasOracle_getL1Fee = "getL1Fee"
-
- // ScrollGasOracleAddress is the address of the precompiled contract that exists on Scroll chain.
- ScrollGasOracleAddress = "0x5300000000000000000000000000000000000002"
- // ScrollGasOracle_l1BaseFee is a hex encoded call to:
- // `function l1BaseFee() external view returns (uint256);`
- ScrollGasOracle_l1BaseFee = "l1BaseFee"
- // ScrollGasOracle_getL1Fee is a hex encoded call to:
- // `function getL1Fee(bytes) external view returns (uint256);`
- ScrollGasOracle_getL1Fee = "getL1Fee"
-
- // GasOracleAddress is the address of the precompiled contract that exists on Kroma chain.
- // This is the case for Kroma.
- KromaGasOracleAddress = "0x4200000000000000000000000000000000000005"
- // GasOracle_l1BaseFee is the a hex encoded call to:
- // `function l1BaseFee() external view returns (uint256);`
- KromaGasOracle_l1BaseFee = "l1BaseFee"
-
// Interval at which to poll for L1BaseFee. A good starting point is the L1 block time.
PollPeriod = 6 * time.Second
)
@@ -117,253 +52,18 @@ func IsRollupWithL1Support(chainType config.ChainType) bool {
return slices.Contains(supportedChainTypes, chainType)
}
-func NewL1GasOracle(lggr logger.Logger, ethClient ethClient, chainType config.ChainType) L1Oracle {
- var priceReader daPriceReader
- switch chainType {
- case config.ChainOptimismBedrock:
- priceReader = newOPPriceReader(lggr, ethClient, chainType, OPGasOracleAddress)
- case config.ChainKroma:
- priceReader = newOPPriceReader(lggr, ethClient, chainType, KromaGasOracleAddress)
- default:
- priceReader = nil
+func NewL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainType config.ChainType) L1Oracle {
+ if !IsRollupWithL1Support(chainType) {
+ return nil
}
- return newL1GasOracle(lggr, ethClient, chainType, priceReader)
-}
-
-func newL1GasOracle(lggr logger.Logger, ethClient ethClient, chainType config.ChainType, priceReader daPriceReader) L1Oracle {
- var l1GasPriceAddress, gasPriceMethod, l1GasCostAddress, gasCostMethod string
- var l1GasPriceMethodAbi, l1GasCostMethodAbi abi.ABI
- var gasPriceErr, gasCostErr error
-
+ var l1Oracle L1Oracle
switch chainType {
+ case config.ChainOptimismBedrock, config.ChainKroma, config.ChainScroll:
+ l1Oracle = NewOpStackL1GasOracle(lggr, ethClient, chainType)
case config.ChainArbitrum:
- l1GasPriceAddress = ArbGasInfoAddress
- gasPriceMethod = ArbGasInfo_getL1BaseFeeEstimate
- l1GasPriceMethodAbi, gasPriceErr = abi.JSON(strings.NewReader(GetL1BaseFeeEstimateAbiString))
- l1GasCostAddress = ArbNodeInterfaceAddress
- gasCostMethod = ArbNodeInterface_gasEstimateL1Component
- l1GasCostMethodAbi, gasCostErr = abi.JSON(strings.NewReader(GasEstimateL1ComponentAbiString))
- case config.ChainOptimismBedrock:
- l1GasPriceAddress = OPGasOracleAddress
- gasPriceMethod = OPGasOracle_l1BaseFee
- l1GasPriceMethodAbi, gasPriceErr = abi.JSON(strings.NewReader(L1BaseFeeAbiString))
- l1GasCostAddress = OPGasOracleAddress
- gasCostMethod = OPGasOracle_getL1Fee
- l1GasCostMethodAbi, gasCostErr = abi.JSON(strings.NewReader(GetL1FeeAbiString))
- case config.ChainKroma:
- l1GasPriceAddress = KromaGasOracleAddress
- gasPriceMethod = KromaGasOracle_l1BaseFee
- l1GasPriceMethodAbi, gasPriceErr = abi.JSON(strings.NewReader(L1BaseFeeAbiString))
- l1GasCostAddress = ""
- gasCostMethod = ""
- case config.ChainScroll:
- l1GasPriceAddress = ScrollGasOracleAddress
- gasPriceMethod = ScrollGasOracle_l1BaseFee
- l1GasPriceMethodAbi, gasPriceErr = abi.JSON(strings.NewReader(L1BaseFeeAbiString))
- l1GasCostAddress = ScrollGasOracleAddress
- gasCostMethod = ScrollGasOracle_getL1Fee
- l1GasCostMethodAbi, gasCostErr = abi.JSON(strings.NewReader(GetL1FeeAbiString))
+ l1Oracle = NewArbitrumL1GasOracle(lggr, ethClient)
default:
panic(fmt.Sprintf("Received unspported chaintype %s", chainType))
}
-
- if gasPriceErr != nil {
- panic(fmt.Sprintf("Failed to parse L1 gas price method ABI for chain: %s", chainType))
- }
- if gasCostErr != nil {
- panic(fmt.Sprintf("Failed to parse L1 gas cost method ABI for chain: %s", chainType))
- }
-
- return &l1Oracle{
- client: ethClient,
- pollPeriod: PollPeriod,
- logger: logger.Sugared(logger.Named(lggr, fmt.Sprintf("L1GasOracle(%s)", chainType))),
- chainType: chainType,
-
- l1GasPriceAddress: l1GasPriceAddress,
- gasPriceMethod: gasPriceMethod,
- l1GasPriceMethodAbi: l1GasPriceMethodAbi,
- l1GasCostAddress: l1GasCostAddress,
- gasCostMethod: gasCostMethod,
- l1GasCostMethodAbi: l1GasCostMethodAbi,
-
- priceReader: priceReader,
-
- chInitialised: make(chan struct{}),
- chStop: make(chan struct{}),
- chDone: make(chan struct{}),
- }
-}
-
-func (o *l1Oracle) Name() string {
- return o.logger.Name()
-}
-
-func (o *l1Oracle) Start(ctx context.Context) error {
- return o.StartOnce(o.Name(), func() error {
- go o.run()
- <-o.chInitialised
- return nil
- })
-}
-func (o *l1Oracle) Close() error {
- return o.StopOnce(o.Name(), func() error {
- close(o.chStop)
- <-o.chDone
- return nil
- })
-}
-
-func (o *l1Oracle) HealthReport() map[string]error {
- return map[string]error{o.Name(): o.Healthy()}
-}
-
-func (o *l1Oracle) run() {
- defer close(o.chDone)
-
- t := o.refresh()
- close(o.chInitialised)
-
- for {
- select {
- case <-o.chStop:
- return
- case <-t.C:
- t = o.refresh()
- }
- }
-}
-func (o *l1Oracle) refresh() (t *time.Timer) {
- t, err := o.refreshWithError()
- if err != nil {
- o.SvcErrBuffer.Append(err)
- }
- return
-}
-
-func (o *l1Oracle) refreshWithError() (t *time.Timer, err error) {
- t = time.NewTimer(utils.WithJitter(o.pollPeriod))
-
- ctx, cancel := o.chStop.CtxCancel(evmclient.ContextWithDefaultTimeout())
- defer cancel()
-
- price, err := o.fetchL1GasPrice(ctx)
- if err != nil {
- return t, err
- }
-
- o.l1GasPriceMu.Lock()
- defer o.l1GasPriceMu.Unlock()
- o.l1GasPrice = priceEntry{price: assets.NewWei(price), timestamp: time.Now()}
- return
-}
-
-func (o *l1Oracle) fetchL1GasPrice(ctx context.Context) (price *big.Int, err error) {
- // if dedicated priceReader exists, use the reader
- if o.priceReader != nil {
- return o.priceReader.GetDAGasPrice(ctx)
- }
-
- var callData, b []byte
- precompile := common.HexToAddress(o.l1GasPriceAddress)
- callData, err = o.l1GasPriceMethodAbi.Pack(o.gasPriceMethod)
- if err != nil {
- errMsg := fmt.Sprintf("failed to pack calldata for %s L1 gas price method", o.chainType)
- o.logger.Errorf(errMsg)
- return nil, fmt.Errorf("%s: %w", errMsg, err)
- }
- b, err = o.client.CallContract(ctx, ethereum.CallMsg{
- To: &precompile,
- Data: callData,
- }, nil)
- if err != nil {
- errMsg := "gas oracle contract call failed"
- o.logger.Errorf(errMsg)
- return nil, fmt.Errorf("%s: %w", errMsg, err)
- }
-
- if len(b) != 32 { // returns uint256;
- errMsg := fmt.Sprintf("return data length (%d) different than expected (%d)", len(b), 32)
- o.logger.Criticalf(errMsg)
- return nil, fmt.Errorf(errMsg)
- }
- price = new(big.Int).SetBytes(b)
- return price, nil
-}
-
-func (o *l1Oracle) GasPrice(_ context.Context) (l1GasPrice *assets.Wei, err error) {
- var timestamp time.Time
- ok := o.IfStarted(func() {
- o.l1GasPriceMu.RLock()
- l1GasPrice = o.l1GasPrice.price
- timestamp = o.l1GasPrice.timestamp
- o.l1GasPriceMu.RUnlock()
- })
- if !ok {
- return l1GasPrice, fmt.Errorf("L1GasOracle is not started; cannot estimate gas")
- }
- if l1GasPrice == nil {
- return l1GasPrice, fmt.Errorf("failed to get l1 gas price; gas price not set")
- }
- // Validate the price has been updated within the pollPeriod * 2
- // Allowing double the poll period before declaring the price stale to give ample time for the refresh to process
- if time.Since(timestamp) > o.pollPeriod*2 {
- return l1GasPrice, fmt.Errorf("gas price is stale")
- }
- return
-}
-
-// Gets the L1 gas cost for the provided transaction at the specified block num
-// If block num is not provided, the value on the latest block num is used
-func (o *l1Oracle) GetGasCost(ctx context.Context, tx *gethtypes.Transaction, blockNum *big.Int) (*assets.Wei, error) {
- ctx, cancel := context.WithTimeout(ctx, client.QueryTimeout)
- defer cancel()
- var callData, b []byte
- var err error
- if o.chainType == config.ChainOptimismBedrock || o.chainType == config.ChainScroll {
- // Append rlp-encoded tx
- var encodedtx []byte
- if encodedtx, err = tx.MarshalBinary(); err != nil {
- return nil, fmt.Errorf("failed to marshal tx for gas cost estimation: %w", err)
- }
- if callData, err = o.l1GasCostMethodAbi.Pack(o.gasCostMethod, encodedtx); err != nil {
- return nil, fmt.Errorf("failed to pack calldata for %s L1 gas cost estimation method: %w", o.chainType, err)
- }
- } else if o.chainType == config.ChainArbitrum {
- if callData, err = o.l1GasCostMethodAbi.Pack(o.gasCostMethod, tx.To(), false, tx.Data()); err != nil {
- return nil, fmt.Errorf("failed to pack calldata for %s L1 gas cost estimation method: %w", o.chainType, err)
- }
- } else {
- return nil, fmt.Errorf("L1 gas cost not supported for this chain: %s", o.chainType)
- }
-
- precompile := common.HexToAddress(o.l1GasCostAddress)
- b, err = o.client.CallContract(ctx, ethereum.CallMsg{
- To: &precompile,
- Data: callData,
- }, blockNum)
- if err != nil {
- errorMsg := fmt.Sprintf("gas oracle contract call failed: %v", err)
- o.logger.Errorf(errorMsg)
- return nil, fmt.Errorf(errorMsg)
- }
-
- var l1GasCost *big.Int
- if o.chainType == config.ChainOptimismBedrock || o.chainType == config.ChainScroll {
- if len(b) != 32 { // returns uint256;
- errorMsg := fmt.Sprintf("return data length (%d) different than expected (%d)", len(b), 32)
- o.logger.Critical(errorMsg)
- return nil, fmt.Errorf(errorMsg)
- }
- l1GasCost = new(big.Int).SetBytes(b)
- } else if o.chainType == config.ChainArbitrum {
- if len(b) != 8+2*32 { // returns (uint64 gasEstimateForL1, uint256 baseFee, uint256 l1BaseFeeEstimate);
- errorMsg := fmt.Sprintf("return data length (%d) different than expected (%d)", len(b), 8+2*32)
- o.logger.Critical(errorMsg)
- return nil, fmt.Errorf(errorMsg)
- }
- l1GasCost = new(big.Int).SetBytes(b[:8])
- }
-
- return assets.NewWei(l1GasCost), nil
+ return l1Oracle
}
diff --git a/core/chains/evm/gas/rollups/l1_oracle_test.go b/core/chains/evm/gas/rollups/l1_oracle_test.go
index 4f3b67e2ecf..6efdda6bcff 100644
--- a/core/chains/evm/gas/rollups/l1_oracle_test.go
+++ b/core/chains/evm/gas/rollups/l1_oracle_test.go
@@ -1,6 +1,7 @@
package rollups
import (
+ "errors"
"math/big"
"strings"
"testing"
@@ -27,9 +28,9 @@ func TestL1Oracle(t *testing.T) {
t.Parallel()
t.Run("Unsupported ChainType returns nil", func(t *testing.T) {
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
- assert.Panicsf(t, func() { NewL1GasOracle(logger.Test(t), ethClient, config.ChainCelo) }, "Received unspported chaintype %s", config.ChainCelo)
+ assert.Nil(t, NewL1GasOracle(logger.Test(t), ethClient, config.ChainCelo))
})
}
@@ -37,7 +38,7 @@ func TestL1Oracle_GasPrice(t *testing.T) {
t.Parallel()
t.Run("Calling GasPrice on unstarted L1Oracle returns error", func(t *testing.T) {
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
oracle := NewL1GasOracle(logger.Test(t), ethClient, config.ChainOptimismBedrock)
@@ -50,7 +51,7 @@ func TestL1Oracle_GasPrice(t *testing.T) {
l1GasPriceMethodAbi, err := abi.JSON(strings.NewReader(GetL1BaseFeeEstimateAbiString))
require.NoError(t, err)
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
@@ -73,10 +74,34 @@ func TestL1Oracle_GasPrice(t *testing.T) {
t.Run("Calling GasPrice on started Kroma L1Oracle returns Kroma l1GasPrice", func(t *testing.T) {
l1BaseFee := big.NewInt(100)
- priceReader := mocks.NewDAPriceReader(t)
- priceReader.On("GetDAGasPrice", mock.Anything).Return(l1BaseFee, nil)
+ l1GasPriceMethodAbi, err := abi.JSON(strings.NewReader(L1BaseFeeAbiString))
+ require.NoError(t, err)
+
+ isEcotoneAbiString, err := abi.JSON(strings.NewReader(OPIsEcotoneAbiString))
+ require.NoError(t, err)
+
+ ethClient := mocks.NewL1OracleClient(t)
+ ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ callMsg := args.Get(1).(ethereum.CallMsg)
+ blockNumber := args.Get(2).(*big.Int)
+ var payload []byte
+ payload, err = isEcotoneAbiString.Pack("isEcotone")
+ require.NoError(t, err)
+ require.Equal(t, payload, callMsg.Data)
+ assert.Nil(t, blockNumber)
+ }).Return(nil, errors.New("not ecotone")).Once()
- oracle := newL1GasOracle(logger.Test(t), nil, config.ChainKroma, priceReader)
+ ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ callMsg := args.Get(1).(ethereum.CallMsg)
+ blockNumber := args.Get(2).(*big.Int)
+ var payload []byte
+ payload, err = l1GasPriceMethodAbi.Pack("l1BaseFee")
+ require.NoError(t, err)
+ require.Equal(t, payload, callMsg.Data)
+ assert.Nil(t, blockNumber)
+ }).Return(common.BigToHash(l1BaseFee).Bytes(), nil)
+
+ oracle := newOpStackL1GasOracle(logger.Test(t), ethClient, config.ChainKroma, KromaGasOracleAddress)
servicetest.RunHealthy(t, oracle)
gasPrice, err := oracle.GasPrice(testutils.Context(t))
@@ -88,10 +113,34 @@ func TestL1Oracle_GasPrice(t *testing.T) {
t.Run("Calling GasPrice on started OPStack L1Oracle returns OPStack l1GasPrice", func(t *testing.T) {
l1BaseFee := big.NewInt(100)
- priceReader := mocks.NewDAPriceReader(t)
- priceReader.On("GetDAGasPrice", mock.Anything).Return(l1BaseFee, nil)
+ l1GasPriceMethodAbi, err := abi.JSON(strings.NewReader(L1BaseFeeAbiString))
+ require.NoError(t, err)
+
+ isEcotoneAbiString, err := abi.JSON(strings.NewReader(OPIsEcotoneAbiString))
+ require.NoError(t, err)
+
+ ethClient := mocks.NewL1OracleClient(t)
+ ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ callMsg := args.Get(1).(ethereum.CallMsg)
+ blockNumber := args.Get(2).(*big.Int)
+ var payload []byte
+ payload, err = isEcotoneAbiString.Pack("isEcotone")
+ require.NoError(t, err)
+ require.Equal(t, payload, callMsg.Data)
+ assert.Nil(t, blockNumber)
+ }).Return(nil, errors.New("not ecotone")).Once()
- oracle := newL1GasOracle(logger.Test(t), nil, config.ChainOptimismBedrock, priceReader)
+ ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ callMsg := args.Get(1).(ethereum.CallMsg)
+ blockNumber := args.Get(2).(*big.Int)
+ var payload []byte
+ payload, err = l1GasPriceMethodAbi.Pack("l1BaseFee")
+ require.NoError(t, err)
+ require.Equal(t, payload, callMsg.Data)
+ assert.Nil(t, blockNumber)
+ }).Return(common.BigToHash(l1BaseFee).Bytes(), nil)
+
+ oracle := newOpStackL1GasOracle(logger.Test(t), ethClient, config.ChainOptimismBedrock, OPGasOracleAddress)
servicetest.RunHealthy(t, oracle)
gasPrice, err := oracle.GasPrice(testutils.Context(t))
@@ -105,7 +154,20 @@ func TestL1Oracle_GasPrice(t *testing.T) {
l1GasPriceMethodAbi, err := abi.JSON(strings.NewReader(L1BaseFeeAbiString))
require.NoError(t, err)
- ethClient := mocks.NewETHClient(t)
+ isEcotoneAbiString, err := abi.JSON(strings.NewReader(OPIsEcotoneAbiString))
+ require.NoError(t, err)
+
+ ethClient := mocks.NewL1OracleClient(t)
+ ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ callMsg := args.Get(1).(ethereum.CallMsg)
+ blockNumber := args.Get(2).(*big.Int)
+ var payload []byte
+ payload, err = isEcotoneAbiString.Pack("isEcotone")
+ require.NoError(t, err)
+ require.Equal(t, payload, callMsg.Data)
+ assert.Nil(t, blockNumber)
+ }).Return(nil, errors.New("not ecotone")).Once()
+
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
@@ -149,7 +211,7 @@ func TestL1Oracle_GetGasCost(t *testing.T) {
result = append(result, baseFee...)
result = append(result, l1BaseFeeEstimate...)
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
@@ -171,7 +233,7 @@ func TestL1Oracle_GetGasCost(t *testing.T) {
blockNum := big.NewInt(1000)
tx := types.NewTx(&types.LegacyTx{})
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
oracle := NewL1GasOracle(logger.Test(t), ethClient, config.ChainKroma)
_, err := oracle.GetGasCost(testutils.Context(t), tx, blockNum)
@@ -195,7 +257,7 @@ func TestL1Oracle_GetGasCost(t *testing.T) {
encodedTx, err := tx.MarshalBinary()
require.NoError(t, err)
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
@@ -230,7 +292,7 @@ func TestL1Oracle_GetGasCost(t *testing.T) {
encodedTx, err := tx.MarshalBinary()
require.NoError(t, err)
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
diff --git a/core/chains/evm/gas/rollups/mocks/da_price_reader.go b/core/chains/evm/gas/rollups/mocks/da_price_reader.go
deleted file mode 100644
index 7758f53e436..00000000000
--- a/core/chains/evm/gas/rollups/mocks/da_price_reader.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Code generated by mockery v2.38.0. DO NOT EDIT.
-
-package mocks
-
-import (
- context "context"
- big "math/big"
-
- mock "github.com/stretchr/testify/mock"
-)
-
-// DAPriceReader is an autogenerated mock type for the daPriceReader type
-type DAPriceReader struct {
- mock.Mock
-}
-
-// GetDAGasPrice provides a mock function with given fields: ctx
-func (_m *DAPriceReader) GetDAGasPrice(ctx context.Context) (*big.Int, error) {
- ret := _m.Called(ctx)
-
- if len(ret) == 0 {
- panic("no return value specified for GetDAGasPrice")
- }
-
- var r0 *big.Int
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context) (*big.Int, error)); ok {
- return rf(ctx)
- }
- if rf, ok := ret.Get(0).(func(context.Context) *big.Int); ok {
- r0 = rf(ctx)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(*big.Int)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context) error); ok {
- r1 = rf(ctx)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// NewDAPriceReader creates a new instance of DAPriceReader. 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 NewDAPriceReader(t interface {
- mock.TestingT
- Cleanup(func())
-}) *DAPriceReader {
- mock := &DAPriceReader{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/core/chains/evm/gas/rollups/mocks/eth_client.go b/core/chains/evm/gas/rollups/mocks/l1_oracle_client.go
similarity index 72%
rename from core/chains/evm/gas/rollups/mocks/eth_client.go
rename to core/chains/evm/gas/rollups/mocks/l1_oracle_client.go
index e5a28f715ad..3995a09513b 100644
--- a/core/chains/evm/gas/rollups/mocks/eth_client.go
+++ b/core/chains/evm/gas/rollups/mocks/l1_oracle_client.go
@@ -13,13 +13,13 @@ import (
rpc "github.com/ethereum/go-ethereum/rpc"
)
-// ETHClient is an autogenerated mock type for the ethClient type
-type ETHClient struct {
+// L1OracleClient is an autogenerated mock type for the l1OracleClient type
+type L1OracleClient struct {
mock.Mock
}
// BatchCallContext provides a mock function with given fields: ctx, b
-func (_m *ETHClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error {
+func (_m *L1OracleClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error {
ret := _m.Called(ctx, b)
if len(ret) == 0 {
@@ -37,7 +37,7 @@ func (_m *ETHClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) er
}
// CallContract provides a mock function with given fields: ctx, msg, blockNumber
-func (_m *ETHClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
+func (_m *L1OracleClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
ret := _m.Called(ctx, msg, blockNumber)
if len(ret) == 0 {
@@ -66,13 +66,13 @@ func (_m *ETHClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blo
return r0, r1
}
-// NewETHClient creates a new instance of ETHClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// NewL1OracleClient creates a new instance of L1OracleClient. 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 NewETHClient(t interface {
+func NewL1OracleClient(t interface {
mock.TestingT
Cleanup(func())
-}) *ETHClient {
- mock := ÐClient{}
+}) *L1OracleClient {
+ mock := &L1OracleClient{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
diff --git a/core/chains/evm/gas/rollups/models.go b/core/chains/evm/gas/rollups/models.go
deleted file mode 100644
index 7aa3d4059dd..00000000000
--- a/core/chains/evm/gas/rollups/models.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package rollups
-
-import (
- "context"
- "math/big"
-
- "github.com/ethereum/go-ethereum/core/types"
-
- "github.com/smartcontractkit/chainlink-common/pkg/services"
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
-)
-
-// L1Oracle provides interface for fetching L1-specific fee components if the chain is an L2.
-// For example, on Optimistic Rollups, this oracle can return rollup-specific l1BaseFee
-//
-//go:generate mockery --quiet --name L1Oracle --output ./mocks/ --case=underscore
-type L1Oracle interface {
- services.Service
-
- GasPrice(ctx context.Context) (*assets.Wei, error)
- GetGasCost(ctx context.Context, tx *types.Transaction, blockNum *big.Int) (*assets.Wei, error)
-}
diff --git a/core/chains/evm/gas/rollups/op_l1_oracle.go b/core/chains/evm/gas/rollups/op_l1_oracle.go
new file mode 100644
index 00000000000..e180777fb61
--- /dev/null
+++ b/core/chains/evm/gas/rollups/op_l1_oracle.go
@@ -0,0 +1,431 @@
+package rollups
+
+import (
+ "context"
+ "fmt"
+ "math/big"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/rpc"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/logger"
+ "github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/utils"
+
+ gethtypes "github.com/ethereum/go-ethereum/core/types"
+
+ "github.com/smartcontractkit/chainlink/v2/common/client"
+ "github.com/smartcontractkit/chainlink/v2/common/config"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
+ evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+)
+
+// Reads L2-specific precompiles and caches the l1GasPrice set by the L2.
+type OptimismL1Oracle struct {
+ services.StateMachine
+ client l1OracleClient
+ pollPeriod time.Duration
+ logger logger.SugaredLogger
+ chainType config.ChainType
+
+ l1OracleAddress string
+ gasPriceMethod string
+ l1GasPriceMethodAbi abi.ABI
+ l1GasPriceMu sync.RWMutex
+ l1GasPrice priceEntry
+
+ gasCostMethod string
+ l1GasCostMethodAbi abi.ABI
+
+ chInitialised chan struct{}
+ chStop services.StopChan
+ chDone chan struct{}
+
+ isEcotoneMethodAbi abi.ABI
+
+ l1BaseFeeCalldata []byte
+ isEcotoneCalldata []byte
+ getL1GasUsedCalldata []byte
+ getL1FeeCalldata []byte
+
+ isEcotone bool
+ isEcotoneCheckTs int64
+}
+
+const (
+ // OPStackGasOracle_isEcotone fetches if the OP Stack GasPriceOracle contract has upgraded to Ecotone
+ OPStackGasOracle_isEcotone = "isEcotone"
+ // OPStackGasOracle_getL1GasUsed fetches the l1 gas used for given tx bytes
+ OPStackGasOracle_getL1GasUsed = "getL1GasUsed"
+ // OPStackGasOracle_isEcotonePollingPeriod is the interval to poll if chain has upgraded to Ecotone
+ // Set to poll every 4 hours
+ OPStackGasOracle_isEcotonePollingPeriod = 14400
+ // OPStackGasOracleAddress is the address of the precompiled contract that exists on OP stack chain.
+ // OPStackGasOracle_l1BaseFee fetches the l1 base fee set in the OP Stack GasPriceOracle contract
+ // OPStackGasOracle_l1BaseFee is a hex encoded call to:
+ // `function l1BaseFee() external view returns (uint256);`
+ OPStackGasOracle_l1BaseFee = "l1BaseFee"
+ // OPStackGasOracle_getL1Fee fetches the l1 fee for given tx bytes
+ // OPStackGasOracle_getL1Fee is a hex encoded call to:
+ // `function getL1Fee(bytes) external view returns (uint256);`
+ OPStackGasOracle_getL1Fee = "getL1Fee"
+ // This is the case for Optimism and Base.
+ OPGasOracleAddress = "0x420000000000000000000000000000000000000F"
+ // GasOracleAddress is the address of the precompiled contract that exists on Kroma chain.
+ // This is the case for Kroma.
+ KromaGasOracleAddress = "0x4200000000000000000000000000000000000005"
+ // ScrollGasOracleAddress is the address of the precompiled contract that exists on Scroll chain.
+ ScrollGasOracleAddress = "0x5300000000000000000000000000000000000002"
+)
+
+func NewOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainType config.ChainType) *OptimismL1Oracle {
+ var precompileAddress string
+ switch chainType {
+ case config.ChainOptimismBedrock:
+ precompileAddress = OPGasOracleAddress
+ case config.ChainKroma:
+ precompileAddress = KromaGasOracleAddress
+ case config.ChainScroll:
+ precompileAddress = ScrollGasOracleAddress
+ default:
+ panic(fmt.Sprintf("Received unspported chaintype %s", chainType))
+ }
+ return newOpStackL1GasOracle(lggr, ethClient, chainType, precompileAddress)
+}
+
+func newOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainType config.ChainType, precompileAddress string) *OptimismL1Oracle {
+ var l1OracleAddress, gasPriceMethod, gasCostMethod string
+ var l1GasPriceMethodAbi, l1GasCostMethodAbi abi.ABI
+ var gasPriceErr, gasCostErr error
+
+ l1OracleAddress = precompileAddress
+ gasPriceMethod = OPStackGasOracle_l1BaseFee
+ l1GasPriceMethodAbi, gasPriceErr = abi.JSON(strings.NewReader(L1BaseFeeAbiString))
+ gasCostMethod = OPStackGasOracle_getL1Fee
+ l1GasCostMethodAbi, gasCostErr = abi.JSON(strings.NewReader(GetL1FeeAbiString))
+
+ if gasPriceErr != nil {
+ panic(fmt.Sprintf("Failed to parse L1 gas price method ABI for chain: %s", chainType))
+ }
+ if gasCostErr != nil {
+ panic(fmt.Sprintf("Failed to parse L1 gas cost method ABI for chain: %s", chainType))
+ }
+
+ // encode calldata for each method; these calldata will remain the same for each call, we can encode them just once
+ l1BaseFeeMethodAbi, err := abi.JSON(strings.NewReader(L1BaseFeeAbiString))
+ if err != nil {
+ panic(fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", OPStackGasOracle_l1BaseFee, chainType, err))
+ }
+ l1BaseFeeCalldata, err := l1BaseFeeMethodAbi.Pack(OPStackGasOracle_l1BaseFee)
+ if err != nil {
+ panic(fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", OPStackGasOracle_l1BaseFee, chainType, err))
+ }
+
+ isEcotoneMethodAbi, err := abi.JSON(strings.NewReader(OPIsEcotoneAbiString))
+ if err != nil {
+ panic(fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", OPStackGasOracle_isEcotone, chainType, err))
+ }
+ isEcotoneCalldata, err := isEcotoneMethodAbi.Pack(OPStackGasOracle_isEcotone)
+ if err != nil {
+ panic(fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", OPStackGasOracle_isEcotone, chainType, err))
+ }
+
+ getL1GasUsedMethodAbi, err := abi.JSON(strings.NewReader(OPGetL1GasUsedAbiString))
+ if err != nil {
+ panic(fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", OPStackGasOracle_getL1GasUsed, chainType, err))
+ }
+ getL1GasUsedCalldata, err := getL1GasUsedMethodAbi.Pack(OPStackGasOracle_getL1GasUsed, []byte{0x1})
+ if err != nil {
+ panic(fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", OPStackGasOracle_getL1GasUsed, chainType, err))
+ }
+
+ getL1FeeMethodAbi, err := abi.JSON(strings.NewReader(GetL1FeeAbiString))
+ if err != nil {
+ panic(fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", OPStackGasOracle_getL1Fee, chainType, err))
+ }
+ getL1FeeCalldata, err := getL1FeeMethodAbi.Pack(OPStackGasOracle_getL1Fee, []byte{0x1})
+ if err != nil {
+ panic(fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", OPStackGasOracle_getL1Fee, chainType, err))
+ }
+
+ return &OptimismL1Oracle{
+ client: ethClient,
+ pollPeriod: PollPeriod,
+ logger: logger.Sugared(logger.Named(lggr, "L1GasOracle(optimismBedrock)")),
+ chainType: chainType,
+
+ l1OracleAddress: l1OracleAddress,
+ gasPriceMethod: gasPriceMethod,
+ l1GasPriceMethodAbi: l1GasPriceMethodAbi,
+ gasCostMethod: gasCostMethod,
+ l1GasCostMethodAbi: l1GasCostMethodAbi,
+
+ chInitialised: make(chan struct{}),
+ chStop: make(chan struct{}),
+ chDone: make(chan struct{}),
+
+ isEcotoneMethodAbi: isEcotoneMethodAbi,
+
+ l1BaseFeeCalldata: l1BaseFeeCalldata,
+ isEcotoneCalldata: isEcotoneCalldata,
+ getL1GasUsedCalldata: getL1GasUsedCalldata,
+ getL1FeeCalldata: getL1FeeCalldata,
+
+ isEcotone: false,
+ isEcotoneCheckTs: 0,
+ }
+}
+
+func (o *OptimismL1Oracle) Name() string {
+ return o.logger.Name()
+}
+
+func (o *OptimismL1Oracle) Start(ctx context.Context) error {
+ return o.StartOnce(o.Name(), func() error {
+ go o.run()
+ <-o.chInitialised
+ return nil
+ })
+}
+func (o *OptimismL1Oracle) Close() error {
+ return o.StopOnce(o.Name(), func() error {
+ close(o.chStop)
+ <-o.chDone
+ return nil
+ })
+}
+
+func (o *OptimismL1Oracle) HealthReport() map[string]error {
+ return map[string]error{o.Name(): o.Healthy()}
+}
+
+func (o *OptimismL1Oracle) run() {
+ defer close(o.chDone)
+
+ t := o.refresh()
+ close(o.chInitialised)
+
+ for {
+ select {
+ case <-o.chStop:
+ return
+ case <-t.C:
+ t = o.refresh()
+ }
+ }
+}
+func (o *OptimismL1Oracle) refresh() (t *time.Timer) {
+ t, err := o.refreshWithError()
+ if err != nil {
+ o.SvcErrBuffer.Append(err)
+ }
+ return
+}
+
+func (o *OptimismL1Oracle) refreshWithError() (t *time.Timer, err error) {
+ t = time.NewTimer(utils.WithJitter(o.pollPeriod))
+
+ ctx, cancel := o.chStop.CtxCancel(evmclient.ContextWithDefaultTimeout())
+ defer cancel()
+
+ price, err := o.GetDAGasPrice(ctx)
+ if err != nil {
+ return t, err
+ }
+
+ o.l1GasPriceMu.Lock()
+ defer o.l1GasPriceMu.Unlock()
+ o.l1GasPrice = priceEntry{price: assets.NewWei(price), timestamp: time.Now()}
+ return
+}
+
+func (o *OptimismL1Oracle) GasPrice(_ context.Context) (l1GasPrice *assets.Wei, err error) {
+ var timestamp time.Time
+ ok := o.IfStarted(func() {
+ o.l1GasPriceMu.RLock()
+ l1GasPrice = o.l1GasPrice.price
+ timestamp = o.l1GasPrice.timestamp
+ o.l1GasPriceMu.RUnlock()
+ })
+ if !ok {
+ return l1GasPrice, fmt.Errorf("L1GasOracle is not started; cannot estimate gas")
+ }
+ if l1GasPrice == nil {
+ return l1GasPrice, fmt.Errorf("failed to get l1 gas price; gas price not set")
+ }
+ // Validate the price has been updated within the pollPeriod * 2
+ // Allowing double the poll period before declaring the price stale to give ample time for the refresh to process
+ if time.Since(timestamp) > o.pollPeriod*2 {
+ return l1GasPrice, fmt.Errorf("gas price is stale")
+ }
+ return
+}
+
+// Gets the L1 gas cost for the provided transaction at the specified block num
+// If block num is not provided, the value on the latest block num is used
+func (o *OptimismL1Oracle) GetGasCost(ctx context.Context, tx *gethtypes.Transaction, blockNum *big.Int) (*assets.Wei, error) {
+ ctx, cancel := context.WithTimeout(ctx, client.QueryTimeout)
+ defer cancel()
+ var callData, b []byte
+ var err error
+ if o.chainType == config.ChainKroma {
+ return nil, fmt.Errorf("L1 gas cost not supported for this chain: %s", o.chainType)
+ }
+ // Append rlp-encoded tx
+ var encodedtx []byte
+ if encodedtx, err = tx.MarshalBinary(); err != nil {
+ return nil, fmt.Errorf("failed to marshal tx for gas cost estimation: %w", err)
+ }
+ if callData, err = o.l1GasCostMethodAbi.Pack(o.gasCostMethod, encodedtx); err != nil {
+ return nil, fmt.Errorf("failed to pack calldata for %s L1 gas cost estimation method: %w", o.chainType, err)
+ }
+
+ precompile := common.HexToAddress(o.l1OracleAddress)
+ b, err = o.client.CallContract(ctx, ethereum.CallMsg{
+ To: &precompile,
+ Data: callData,
+ }, blockNum)
+ if err != nil {
+ errorMsg := fmt.Sprintf("gas oracle contract call failed: %v", err)
+ o.logger.Errorf(errorMsg)
+ return nil, fmt.Errorf(errorMsg)
+ }
+
+ var l1GasCost *big.Int
+ if len(b) != 32 { // returns uint256;
+ errorMsg := fmt.Sprintf("return data length (%d) different than expected (%d)", len(b), 32)
+ o.logger.Critical(errorMsg)
+ return nil, fmt.Errorf(errorMsg)
+ }
+ l1GasCost = new(big.Int).SetBytes(b)
+
+ return assets.NewWei(l1GasCost), nil
+}
+
+func (o *OptimismL1Oracle) GetDAGasPrice(ctx context.Context) (*big.Int, error) {
+ isEcotone, err := o.checkIsEcotone(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ o.logger.Infof("Chain isEcotone result: %t", isEcotone)
+
+ if isEcotone {
+ return o.getEcotoneGasPrice(ctx)
+ }
+
+ return o.getV1GasPrice(ctx)
+}
+
+func (o *OptimismL1Oracle) checkIsEcotone(ctx context.Context) (bool, error) {
+ // if chain is already Ecotone, NOOP
+ if o.isEcotone {
+ return true, nil
+ }
+ // if time since last check has not exceeded polling period, NOOP
+ if time.Now().Unix()-o.isEcotoneCheckTs < OPStackGasOracle_isEcotonePollingPeriod {
+ return false, nil
+ }
+ o.isEcotoneCheckTs = time.Now().Unix()
+
+ l1OracleAddress := common.HexToAddress(o.l1OracleAddress)
+ // confirmed with OP team that isEcotone() is the canonical way to check if the chain has upgraded
+ b, err := o.client.CallContract(ctx, ethereum.CallMsg{
+ To: &l1OracleAddress,
+ Data: o.isEcotoneCalldata,
+ }, nil)
+
+ // if the chain has not upgraded to Ecotone, the isEcotone call will revert, this would be expected
+ if err != nil {
+ o.logger.Infof("isEcotone() call failed, this can happen if chain has not upgraded: %w", err)
+ return false, nil
+ }
+
+ res, err := o.isEcotoneMethodAbi.Unpack(OPStackGasOracle_isEcotone, b)
+ if err != nil {
+ return false, fmt.Errorf("failed to unpack isEcotone() return data: %w", err)
+ }
+ o.isEcotone = res[0].(bool)
+ return o.isEcotone, nil
+}
+
+func (o *OptimismL1Oracle) getV1GasPrice(ctx context.Context) (*big.Int, error) {
+ l1OracleAddress := common.HexToAddress(o.l1OracleAddress)
+ b, err := o.client.CallContract(ctx, ethereum.CallMsg{
+ To: &l1OracleAddress,
+ Data: o.l1BaseFeeCalldata,
+ }, nil)
+ if err != nil {
+ return nil, fmt.Errorf("l1BaseFee() call failed: %w", err)
+ }
+
+ if len(b) != 32 {
+ return nil, fmt.Errorf("l1BaseFee() return data length (%d) different than expected (%d)", len(b), 32)
+ }
+ return new(big.Int).SetBytes(b), nil
+}
+
+func (o *OptimismL1Oracle) getEcotoneGasPrice(ctx context.Context) (*big.Int, error) {
+ rpcBatchCalls := []rpc.BatchElem{
+ {
+ Method: "eth_call",
+ Args: []any{
+ map[string]interface{}{
+ "from": common.Address{},
+ "to": o.l1OracleAddress,
+ "data": hexutil.Bytes(o.getL1GasUsedCalldata),
+ },
+ "latest",
+ },
+ Result: new(string),
+ },
+ {
+ Method: "eth_call",
+ Args: []any{
+ map[string]interface{}{
+ "from": common.Address{},
+ "to": o.l1OracleAddress,
+ "data": hexutil.Bytes(o.getL1FeeCalldata),
+ },
+ "latest",
+ },
+ Result: new(string),
+ },
+ }
+
+ err := o.client.BatchCallContext(ctx, rpcBatchCalls)
+ if err != nil {
+ return nil, fmt.Errorf("getEcotoneGasPrice batch call failed: %w", err)
+ }
+ if rpcBatchCalls[0].Error != nil {
+ return nil, fmt.Errorf("%s call failed in a batch: %w", OPStackGasOracle_getL1GasUsed, err)
+ }
+ if rpcBatchCalls[1].Error != nil {
+ return nil, fmt.Errorf("%s call failed in a batch: %w", OPStackGasOracle_getL1Fee, err)
+ }
+
+ l1GasUsedResult := *(rpcBatchCalls[0].Result.(*string))
+ l1FeeResult := *(rpcBatchCalls[1].Result.(*string))
+
+ l1GasUsedBytes, err := hexutil.Decode(l1GasUsedResult)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decode %s rpc result: %w", OPStackGasOracle_getL1GasUsed, err)
+ }
+ l1FeeBytes, err := hexutil.Decode(l1FeeResult)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decode %s rpc result: %w", OPStackGasOracle_getL1Fee, err)
+ }
+
+ l1GasUsed := new(big.Int).SetBytes(l1GasUsedBytes)
+ l1Fee := new(big.Int).SetBytes(l1FeeBytes)
+
+ // for the same tx byte, l1Fee / l1GasUsed will give the l1 gas price
+ // note this price is per l1 gas, not l1 data byte
+ return new(big.Int).Div(l1Fee, l1GasUsed), nil
+}
diff --git a/core/chains/evm/gas/rollups/op_price_reader_test.go b/core/chains/evm/gas/rollups/op_l1_oracle_test.go
similarity index 90%
rename from core/chains/evm/gas/rollups/op_price_reader_test.go
rename to core/chains/evm/gas/rollups/op_l1_oracle_test.go
index dad12a16366..36e8700faff 100644
--- a/core/chains/evm/gas/rollups/op_price_reader_test.go
+++ b/core/chains/evm/gas/rollups/op_l1_oracle_test.go
@@ -60,7 +60,7 @@ func TestDAPriceReader_ReadV1GasPrice(t *testing.T) {
isEcotoneCalldata, err := isEcotoneMethodAbi.Pack(OPStackGasOracle_isEcotone)
require.NoError(t, err)
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
call := ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
@@ -87,7 +87,7 @@ func TestDAPriceReader_ReadV1GasPrice(t *testing.T) {
}).Return(common.BigToHash(l1BaseFee).Bytes(), nil).Once()
}
- oracle := newOPPriceReader(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
+ oracle := newOpStackL1GasOracle(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
gasPrice, err := oracle.GetDAGasPrice(testutils.Context(t))
if tc.returnBadData {
@@ -100,13 +100,13 @@ func TestDAPriceReader_ReadV1GasPrice(t *testing.T) {
}
}
-func setupIsEcotone(t *testing.T, oracleAddress string) *mocks.ETHClient {
+func setupIsEcotone(t *testing.T, oracleAddress string) *mocks.L1OracleClient {
isEcotoneMethodAbi, err := abi.JSON(strings.NewReader(OPIsEcotoneAbiString))
require.NoError(t, err)
isEcotoneCalldata, err := isEcotoneMethodAbi.Pack(OPStackGasOracle_isEcotone)
require.NoError(t, err)
- ethClient := mocks.NewETHClient(t)
+ ethClient := mocks.NewL1OracleClient(t)
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
@@ -142,7 +142,7 @@ func TestDAPriceReader_ReadEcotoneGasPrice(t *testing.T) {
for _, rE := range rpcElements {
require.Equal(t, "eth_call", rE.Method)
- require.Equal(t, oracleAddress, rE.Args[0].(map[string]interface{})["to"].(common.Address).String())
+ require.Equal(t, oracleAddress, rE.Args[0].(map[string]interface{})["to"])
require.Equal(t, "latest", rE.Args[1])
}
@@ -155,7 +155,7 @@ func TestDAPriceReader_ReadEcotoneGasPrice(t *testing.T) {
rpcElements[1].Result = &res2
}).Return(nil).Once()
- oracle := newOPPriceReader(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
+ oracle := newOpStackL1GasOracle(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
gasPrice, err := oracle.GetDAGasPrice(testutils.Context(t))
require.NoError(t, err)
assert.Equal(t, l1BaseFee, gasPrice)
@@ -170,7 +170,7 @@ func TestDAPriceReader_ReadEcotoneGasPrice(t *testing.T) {
rpcElements[1].Result = &badData
}).Return(nil).Once()
- oracle := newOPPriceReader(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
+ oracle := newOpStackL1GasOracle(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
_, err := oracle.GetDAGasPrice(testutils.Context(t))
assert.Error(t, err)
})
@@ -179,7 +179,7 @@ func TestDAPriceReader_ReadEcotoneGasPrice(t *testing.T) {
ethClient := setupIsEcotone(t, oracleAddress)
ethClient.On("BatchCallContext", mock.Anything, mock.IsType([]rpc.BatchElem{})).Return(fmt.Errorf("revert")).Once()
- oracle := newOPPriceReader(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
+ oracle := newOpStackL1GasOracle(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
_, err := oracle.GetDAGasPrice(testutils.Context(t))
assert.Error(t, err)
})
@@ -193,7 +193,7 @@ func TestDAPriceReader_ReadEcotoneGasPrice(t *testing.T) {
rpcElements[1].Error = fmt.Errorf("revert")
}).Return(nil).Once()
- oracle := newOPPriceReader(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
+ oracle := newOpStackL1GasOracle(logger.Test(t), ethClient, config.ChainOptimismBedrock, oracleAddress)
_, err := oracle.GetDAGasPrice(testutils.Context(t))
assert.Error(t, err)
})
diff --git a/core/chains/evm/gas/rollups/op_price_reader.go b/core/chains/evm/gas/rollups/op_price_reader.go
deleted file mode 100644
index 2d3d668ad8b..00000000000
--- a/core/chains/evm/gas/rollups/op_price_reader.go
+++ /dev/null
@@ -1,228 +0,0 @@
-package rollups
-
-import (
- "context"
- "fmt"
- "math/big"
- "strings"
- "time"
-
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/rpc"
-
- "github.com/smartcontractkit/chainlink-common/pkg/logger"
-
- "github.com/smartcontractkit/chainlink/v2/common/config"
-)
-
-const (
- // OPStackGasOracle_l1BaseFee fetches the l1 base fee set in the OP Stack GasPriceOracle contract
- OPStackGasOracle_l1BaseFee = "l1BaseFee"
-
- // OPStackGasOracle_isEcotone fetches if the OP Stack GasPriceOracle contract has upgraded to Ecotone
- OPStackGasOracle_isEcotone = "isEcotone"
-
- // OPStackGasOracle_getL1GasUsed fetches the l1 gas used for given tx bytes
- OPStackGasOracle_getL1GasUsed = "getL1GasUsed"
-
- // OPStackGasOracle_getL1Fee fetches the l1 fee for given tx bytes
- OPStackGasOracle_getL1Fee = "getL1Fee"
-
- // OPStackGasOracle_isEcotonePollingPeriod is the interval to poll if chain has upgraded to Ecotone
- // Set to poll every 4 hours
- OPStackGasOracle_isEcotonePollingPeriod = 14400
-)
-
-type opStackGasPriceReader struct {
- client ethClient
- logger logger.SugaredLogger
-
- oracleAddress common.Address
- isEcotoneMethodAbi abi.ABI
-
- l1BaseFeeCalldata []byte
- isEcotoneCalldata []byte
- getL1GasUsedCalldata []byte
- getL1FeeCalldata []byte
-
- isEcotone bool
- isEcotoneCheckTs int64
-}
-
-func newOPPriceReader(lggr logger.Logger, ethClient ethClient, chainType config.ChainType, oracleAddress string) daPriceReader {
- // encode calldata for each method; these calldata will remain the same for each call, we can encode them just once
- l1BaseFeeMethodAbi, err := abi.JSON(strings.NewReader(L1BaseFeeAbiString))
- if err != nil {
- panic(fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", OPStackGasOracle_l1BaseFee, chainType, err))
- }
- l1BaseFeeCalldata, err := l1BaseFeeMethodAbi.Pack(OPStackGasOracle_l1BaseFee)
- if err != nil {
- panic(fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", OPStackGasOracle_l1BaseFee, chainType, err))
- }
-
- isEcotoneMethodAbi, err := abi.JSON(strings.NewReader(OPIsEcotoneAbiString))
- if err != nil {
- panic(fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", OPStackGasOracle_isEcotone, chainType, err))
- }
- isEcotoneCalldata, err := isEcotoneMethodAbi.Pack(OPStackGasOracle_isEcotone)
- if err != nil {
- panic(fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", OPStackGasOracle_isEcotone, chainType, err))
- }
-
- getL1GasUsedMethodAbi, err := abi.JSON(strings.NewReader(OPGetL1GasUsedAbiString))
- if err != nil {
- panic(fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", OPStackGasOracle_getL1GasUsed, chainType, err))
- }
- getL1GasUsedCalldata, err := getL1GasUsedMethodAbi.Pack(OPStackGasOracle_getL1GasUsed, []byte{0x1})
- if err != nil {
- panic(fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", OPStackGasOracle_getL1GasUsed, chainType, err))
- }
-
- getL1FeeMethodAbi, err := abi.JSON(strings.NewReader(GetL1FeeAbiString))
- if err != nil {
- panic(fmt.Errorf("failed to parse GasPriceOracle %s() method ABI for chain: %s; %w", OPStackGasOracle_getL1Fee, chainType, err))
- }
- getL1FeeCalldata, err := getL1FeeMethodAbi.Pack(OPStackGasOracle_getL1Fee, []byte{0x1})
- if err != nil {
- panic(fmt.Errorf("failed to parse GasPriceOracle %s() calldata for chain: %s; %w", OPStackGasOracle_getL1Fee, chainType, err))
- }
-
- return &opStackGasPriceReader{
- client: ethClient,
- logger: logger.Sugared(logger.Named(lggr, fmt.Sprintf("OPStackGasOracle(%s)", chainType))),
-
- oracleAddress: common.HexToAddress(oracleAddress),
- isEcotoneMethodAbi: isEcotoneMethodAbi,
-
- l1BaseFeeCalldata: l1BaseFeeCalldata,
- isEcotoneCalldata: isEcotoneCalldata,
- getL1GasUsedCalldata: getL1GasUsedCalldata,
- getL1FeeCalldata: getL1FeeCalldata,
-
- isEcotone: false,
- isEcotoneCheckTs: 0,
- }
-}
-
-func (o *opStackGasPriceReader) GetDAGasPrice(ctx context.Context) (*big.Int, error) {
- isEcotone, err := o.checkIsEcotone(ctx)
- if err != nil {
- return nil, err
- }
-
- o.logger.Infof("Chain isEcotone result: %t", isEcotone)
-
- if isEcotone {
- return o.getEcotoneGasPrice(ctx)
- }
-
- return o.getV1GasPrice(ctx)
-}
-
-func (o *opStackGasPriceReader) checkIsEcotone(ctx context.Context) (bool, error) {
- // if chain is already Ecotone, NOOP
- if o.isEcotone {
- return true, nil
- }
- // if time since last check has not exceeded polling period, NOOP
- if time.Now().Unix()-o.isEcotoneCheckTs < OPStackGasOracle_isEcotonePollingPeriod {
- return false, nil
- }
- o.isEcotoneCheckTs = time.Now().Unix()
-
- // confirmed with OP team that isEcotone() is the canonical way to check if the chain has upgraded
- b, err := o.client.CallContract(ctx, ethereum.CallMsg{
- To: &o.oracleAddress,
- Data: o.isEcotoneCalldata,
- }, nil)
-
- // if the chain has not upgraded to Ecotone, the isEcotone call will revert, this would be expected
- if err != nil {
- o.logger.Infof("isEcotone() call failed, this can happen if chain has not upgraded: %w", err)
- return false, nil
- }
-
- res, err := o.isEcotoneMethodAbi.Unpack(OPStackGasOracle_isEcotone, b)
- if err != nil {
- return false, fmt.Errorf("failed to unpack isEcotone() return data: %w", err)
- }
- o.isEcotone = res[0].(bool)
- return o.isEcotone, nil
-}
-
-func (o *opStackGasPriceReader) getV1GasPrice(ctx context.Context) (*big.Int, error) {
- b, err := o.client.CallContract(ctx, ethereum.CallMsg{
- To: &o.oracleAddress,
- Data: o.l1BaseFeeCalldata,
- }, nil)
- if err != nil {
- return nil, fmt.Errorf("l1BaseFee() call failed: %w", err)
- }
-
- if len(b) != 32 {
- return nil, fmt.Errorf("l1BaseFee() return data length (%d) different than expected (%d)", len(b), 32)
- }
- return new(big.Int).SetBytes(b), nil
-}
-
-func (o *opStackGasPriceReader) getEcotoneGasPrice(ctx context.Context) (*big.Int, error) {
- rpcBatchCalls := []rpc.BatchElem{
- {
- Method: "eth_call",
- Args: []any{
- map[string]interface{}{
- "from": common.Address{},
- "to": o.oracleAddress,
- "data": hexutil.Bytes(o.getL1GasUsedCalldata),
- },
- "latest",
- },
- Result: new(string),
- },
- {
- Method: "eth_call",
- Args: []any{
- map[string]interface{}{
- "from": common.Address{},
- "to": o.oracleAddress,
- "data": hexutil.Bytes(o.getL1FeeCalldata),
- },
- "latest",
- },
- Result: new(string),
- },
- }
-
- err := o.client.BatchCallContext(ctx, rpcBatchCalls)
- if err != nil {
- return nil, fmt.Errorf("getEcotoneGasPrice batch call failed: %w", err)
- }
- if rpcBatchCalls[0].Error != nil {
- return nil, fmt.Errorf("%s call failed in a batch: %w", OPStackGasOracle_getL1GasUsed, err)
- }
- if rpcBatchCalls[1].Error != nil {
- return nil, fmt.Errorf("%s call failed in a batch: %w", OPStackGasOracle_getL1Fee, err)
- }
-
- l1GasUsedResult := *(rpcBatchCalls[0].Result.(*string))
- l1FeeResult := *(rpcBatchCalls[1].Result.(*string))
-
- l1GasUsedBytes, err := hexutil.Decode(l1GasUsedResult)
- if err != nil {
- return nil, fmt.Errorf("failed to decode %s rpc result: %w", OPStackGasOracle_getL1GasUsed, err)
- }
- l1FeeBytes, err := hexutil.Decode(l1FeeResult)
- if err != nil {
- return nil, fmt.Errorf("failed to decode %s rpc result: %w", OPStackGasOracle_getL1Fee, err)
- }
-
- l1GasUsed := new(big.Int).SetBytes(l1GasUsedBytes)
- l1Fee := new(big.Int).SetBytes(l1FeeBytes)
-
- // for the same tx byte, l1Fee / l1GasUsed will give the l1 gas price
- // note this price is per l1 gas, not l1 data byte
- return new(big.Int).Div(l1Fee, l1GasUsed), nil
-}
diff --git a/core/chains/evm/gas/suggested_price_estimator.go b/core/chains/evm/gas/suggested_price_estimator.go
index edc1b0f92fa..e947e9109d1 100644
--- a/core/chains/evm/gas/suggested_price_estimator.go
+++ b/core/chains/evm/gas/suggested_price_estimator.go
@@ -19,6 +19,7 @@ import (
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
@@ -31,8 +32,7 @@ type suggestedPriceConfig interface {
BumpMin() *assets.Wei
}
-//go:generate mockery --quiet --name rpcClient --output ./mocks/ --case=underscore --structname RPCClient
-type rpcClient interface {
+type suggestedPriceEstimatorClient interface {
CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
}
@@ -41,7 +41,7 @@ type SuggestedPriceEstimator struct {
services.StateMachine
cfg suggestedPriceConfig
- client rpcClient
+ client suggestedPriceEstimatorClient
pollPeriod time.Duration
logger logger.Logger
@@ -52,10 +52,12 @@ type SuggestedPriceEstimator struct {
chInitialised chan struct{}
chStop services.StopChan
chDone chan struct{}
+
+ l1Oracle rollups.L1Oracle
}
// NewSuggestedPriceEstimator returns a new Estimator which uses the suggested gas price.
-func NewSuggestedPriceEstimator(lggr logger.Logger, client rpcClient, cfg suggestedPriceConfig) EvmEstimator {
+func NewSuggestedPriceEstimator(lggr logger.Logger, client feeEstimatorClient, cfg suggestedPriceConfig, l1Oracle rollups.L1Oracle) EvmEstimator {
return &SuggestedPriceEstimator{
client: client,
pollPeriod: 10 * time.Second,
@@ -65,6 +67,7 @@ func NewSuggestedPriceEstimator(lggr logger.Logger, client rpcClient, cfg sugges
chInitialised: make(chan struct{}),
chStop: make(chan struct{}),
chDone: make(chan struct{}),
+ l1Oracle: l1Oracle,
}
}
@@ -72,6 +75,10 @@ func (o *SuggestedPriceEstimator) Name() string {
return o.logger.Name()
}
+func (o *SuggestedPriceEstimator) L1Oracle() rollups.L1Oracle {
+ return o.l1Oracle
+}
+
func (o *SuggestedPriceEstimator) Start(context.Context) error {
return o.StartOnce("SuggestedPriceEstimator", func() error {
go o.run()
diff --git a/core/chains/evm/gas/suggested_price_estimator_test.go b/core/chains/evm/gas/suggested_price_estimator_test.go
index 0d52d6ab1b9..4f3c4d307d6 100644
--- a/core/chains/evm/gas/suggested_price_estimator_test.go
+++ b/core/chains/evm/gas/suggested_price_estimator_test.go
@@ -15,6 +15,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks"
+ rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
)
@@ -29,20 +30,24 @@ func TestSuggestedPriceEstimator(t *testing.T) {
cfg := &gas.MockGasEstimatorConfig{BumpPercentF: 10, BumpMinF: assets.NewWei(big.NewInt(1)), BumpThresholdF: 1}
t.Run("calling GetLegacyGas on unstarted estimator returns error", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
_, _, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
assert.EqualError(t, err, "estimator is not started")
})
t.Run("calling GetLegacyGas on started estimator returns prices", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(42)
})
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, maxGasPrice)
require.NoError(t, err)
@@ -51,10 +56,12 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("gas price is lower than user specified max gas price", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(42)
})
@@ -68,10 +75,12 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("gas price is lower than global max gas price", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(120)
})
@@ -84,10 +93,12 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling GetLegacyGas on started estimator if initial call failed returns error", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(pkgerrors.New("kaboom"))
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(pkgerrors.New("kaboom"))
servicetest.RunHealthy(t, o)
@@ -96,22 +107,28 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling GetDynamicFee always returns error", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
_, err := o.GetDynamicFee(testutils.Context(t), maxGasPrice)
assert.EqualError(t, err, "dynamic fees are not implemented for this estimator")
})
t.Run("calling BumpLegacyGas on unstarted estimator returns error", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
_, _, err := o.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(42), gasLimit, maxGasPrice, nil)
assert.EqualError(t, err, "estimator is not started")
})
t.Run("calling BumpDynamicFee always returns error", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
fee := gas.DynamicFee{
FeeCap: assets.NewWeiI(42),
TipCap: assets.NewWeiI(5),
@@ -121,13 +138,15 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling BumpLegacyGas on started estimator returns new price buffered with bumpPercent", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(40)
})
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(10), gasLimit, maxGasPrice, nil)
require.NoError(t, err)
@@ -136,14 +155,16 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling BumpLegacyGas on started estimator returns new price buffered with bumpMin", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(40)
})
- testCfg := &gas.MockGasEstimatorConfig{BumpPercentF: 1, BumpMinF: assets.NewWei(big.NewInt(1)), BumpThresholdF: 1}
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, testCfg)
+ testCfg := &gas.MockGasEstimatorConfig{BumpPercentF: 1, BumpMinF: assets.NewWei(big.NewInt(1)), BumpThresholdF: 1, LimitMultiplierF: 1}
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, testCfg, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(10), gasLimit, maxGasPrice, nil)
require.NoError(t, err)
@@ -152,13 +173,15 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling BumpLegacyGas on started estimator returns original price when lower than previous", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(5)
})
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
servicetest.RunHealthy(t, o)
gasPrice, chainSpecificGasLimit, err := o.BumpLegacyGas(testutils.Context(t), assets.NewWeiI(10), gasLimit, maxGasPrice, nil)
require.NoError(t, err)
@@ -167,10 +190,12 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling BumpLegacyGas on started estimator returns error, suggested gas price is higher than max gas price", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(42)
})
@@ -184,10 +209,12 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling BumpLegacyGas on started estimator returns max gas price when suggested price under max but the buffer exceeds it", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
+
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(39)
})
@@ -200,10 +227,12 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling BumpLegacyGas on started estimator if initial call failed returns error", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(pkgerrors.New("kaboom"))
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(pkgerrors.New("kaboom"))
servicetest.RunHealthy(t, o)
@@ -212,14 +241,16 @@ func TestSuggestedPriceEstimator(t *testing.T) {
})
t.Run("calling BumpLegacyGas on started estimator if refresh call failed returns price from previous update", func(t *testing.T) {
- client := mocks.NewRPCClient(t)
- o := gas.NewSuggestedPriceEstimator(logger.Test(t), client, cfg)
+ feeEstimatorClient := mocks.NewFeeEstimatorClient(t)
+ l1Oracle := rollupMocks.NewL1Oracle(t)
+
+ o := gas.NewSuggestedPriceEstimator(logger.Test(t), feeEstimatorClient, cfg, l1Oracle)
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(nil).Run(func(args mock.Arguments) {
res := args.Get(1).(*hexutil.Big)
(*big.Int)(res).SetInt64(40)
}).Once()
- client.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(pkgerrors.New("kaboom"))
+ feeEstimatorClient.On("CallContext", mock.Anything, mock.Anything, "eth_gasPrice").Return(pkgerrors.New("kaboom"))
servicetest.RunHealthy(t, o)
diff --git a/core/chains/evm/headtracker/head_broadcaster.go b/core/chains/evm/headtracker/head_broadcaster.go
index 9929646441a..e235df3752c 100644
--- a/core/chains/evm/headtracker/head_broadcaster.go
+++ b/core/chains/evm/headtracker/head_broadcaster.go
@@ -5,16 +5,13 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink/v2/common/headtracker"
- commontypes "github.com/smartcontractkit/chainlink/v2/common/types"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
type headBroadcaster = headtracker.HeadBroadcaster[*evmtypes.Head, common.Hash]
-var _ commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash] = &headBroadcaster{}
-
func NewHeadBroadcaster(
lggr logger.Logger,
-) *headBroadcaster {
+) headBroadcaster {
return headtracker.NewHeadBroadcaster[*evmtypes.Head, common.Hash](lggr)
}
diff --git a/core/chains/evm/headtracker/head_listener.go b/core/chains/evm/headtracker/head_listener.go
index 242b59e9a82..964d686e803 100644
--- a/core/chains/evm/headtracker/head_listener.go
+++ b/core/chains/evm/headtracker/head_listener.go
@@ -8,20 +8,17 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink/v2/common/headtracker"
- commontypes "github.com/smartcontractkit/chainlink/v2/common/types"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
-type headListener = headtracker.HeadListener[*evmtypes.Head, ethereum.Subscription, *big.Int, common.Hash]
-
-var _ commontypes.HeadListener[*evmtypes.Head, common.Hash] = (*headListener)(nil)
+type headListener = headtracker.HeadListener[*evmtypes.Head, common.Hash]
func NewHeadListener(
lggr logger.Logger,
ethClient evmclient.Client,
config Config, chStop chan struct{},
-) *headListener {
+) headListener {
return headtracker.NewHeadListener[
*evmtypes.Head,
ethereum.Subscription, *big.Int, common.Hash,
diff --git a/core/chains/evm/headtracker/head_listener_test.go b/core/chains/evm/headtracker/head_listener_test.go
index e5131aca422..4e7efb5e809 100644
--- a/core/chains/evm/headtracker/head_listener_test.go
+++ b/core/chains/evm/headtracker/head_listener_test.go
@@ -25,6 +25,7 @@ import (
)
func Test_HeadListener_HappyPath(t *testing.T) {
+ t.Parallel()
// Logic:
// - spawn a listener instance
// - mock SubscribeNewHead/Err/Unsubscribe to track these calls
@@ -91,6 +92,7 @@ func Test_HeadListener_HappyPath(t *testing.T) {
}
func Test_HeadListener_NotReceivingHeads(t *testing.T) {
+ t.Parallel()
// Logic:
// - same as Test_HeadListener_HappyPath, but
// - send one head, make sure ReceivingHeads() is true
@@ -149,6 +151,7 @@ func Test_HeadListener_NotReceivingHeads(t *testing.T) {
}
func Test_HeadListener_SubscriptionErr(t *testing.T) {
+ t.Parallel()
tests := []struct {
name string
err error
diff --git a/core/chains/evm/headtracker/head_saver.go b/core/chains/evm/headtracker/head_saver.go
index 218f9d8366f..8913d2dec21 100644
--- a/core/chains/evm/headtracker/head_saver.go
+++ b/core/chains/evm/headtracker/head_saver.go
@@ -8,7 +8,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/logger"
- commontypes "github.com/smartcontractkit/chainlink/v2/common/types"
+ "github.com/smartcontractkit/chainlink/v2/common/headtracker"
httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
@@ -21,7 +21,7 @@ type headSaver struct {
heads Heads
}
-var _ commontypes.HeadSaver[*evmtypes.Head, common.Hash] = (*headSaver)(nil)
+var _ headtracker.HeadSaver[*evmtypes.Head, common.Hash] = (*headSaver)(nil)
func NewHeadSaver(lggr logger.Logger, orm ORM, config Config, htConfig HeadTrackerConfig) httypes.HeadSaver {
return &headSaver{
diff --git a/core/chains/evm/headtracker/head_tracker.go b/core/chains/evm/headtracker/head_tracker.go
index 1fed1aa0c51..414dba23833 100644
--- a/core/chains/evm/headtracker/head_tracker.go
+++ b/core/chains/evm/headtracker/head_tracker.go
@@ -12,16 +12,11 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
"github.com/smartcontractkit/chainlink/v2/common/headtracker"
- commontypes "github.com/smartcontractkit/chainlink/v2/common/types"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
-type headTracker = headtracker.HeadTracker[*evmtypes.Head, ethereum.Subscription, *big.Int, common.Hash]
-
-var _ commontypes.HeadTracker[*evmtypes.Head, common.Hash] = (*headTracker)(nil)
-
func NewHeadTracker(
lggr logger.Logger,
ethClient evmclient.Client,
diff --git a/core/chains/evm/headtracker/head_tracker_test.go b/core/chains/evm/headtracker/head_tracker_test.go
index cb554196c87..b8bdb1f5703 100644
--- a/core/chains/evm/headtracker/head_tracker_test.go
+++ b/core/chains/evm/headtracker/head_tracker_test.go
@@ -30,7 +30,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox/mailboxtest"
- commonmocks "github.com/smartcontractkit/chainlink/v2/common/types/mocks"
+ htmocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks"
evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker"
httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types"
@@ -468,7 +468,7 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingEnabled(t *testing.T)
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- checker := commonmocks.NewHeadTrackable[*evmtypes.Head, gethCommon.Hash](t)
+ checker := htmocks.NewHeadTrackable[*evmtypes.Head, gethCommon.Hash](t)
orm := headtracker.NewORM(*evmtest.MustGetDefaultChainID(t, config.EVMConfigs()), db)
csCfg := evmtest.NewChainScopedConfig(t, config)
ht := createHeadTrackerWithChecker(t, ethClient, csCfg.EVM(), csCfg.EVM().HeadTracker(), orm, checker)
@@ -597,7 +597,7 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingDisabled(t *testing.T
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- checker := commonmocks.NewHeadTrackable[*evmtypes.Head, gethCommon.Hash](t)
+ checker := htmocks.NewHeadTrackable[*evmtypes.Head, gethCommon.Hash](t)
orm := headtracker.NewORM(cltest.FixtureChainID, db)
evmcfg := evmtest.NewChainScopedConfig(t, config)
ht := createHeadTrackerWithChecker(t, ethClient, evmcfg.EVM(), evmcfg.EVM().HeadTracker(), orm, checker)
diff --git a/core/chains/evm/headtracker/orm.go b/core/chains/evm/headtracker/orm.go
index 8912bafecdf..9d569ade08d 100644
--- a/core/chains/evm/headtracker/orm.go
+++ b/core/chains/evm/headtracker/orm.go
@@ -31,14 +31,14 @@ var _ ORM = &DbORM{}
type DbORM struct {
chainID ubig.Big
- db sqlutil.DataSource
+ ds sqlutil.DataSource
}
// NewORM creates an ORM scoped to chainID.
-func NewORM(chainID big.Int, db sqlutil.DataSource) *DbORM {
+func NewORM(chainID big.Int, ds sqlutil.DataSource) *DbORM {
return &DbORM{
chainID: ubig.Big(chainID),
- db: db,
+ ds: ds,
}
}
@@ -48,19 +48,19 @@ func (orm *DbORM) IdempotentInsertHead(ctx context.Context, head *evmtypes.Head)
INSERT INTO evm.heads (hash, number, parent_hash, created_at, timestamp, l1_block_number, evm_chain_id, base_fee_per_gas) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (evm_chain_id, hash) DO NOTHING`
- _, err := orm.db.ExecContext(ctx, query, head.Hash, head.Number, head.ParentHash, head.CreatedAt, head.Timestamp, head.L1BlockNumber, orm.chainID, head.BaseFeePerGas)
+ _, err := orm.ds.ExecContext(ctx, query, head.Hash, head.Number, head.ParentHash, head.CreatedAt, head.Timestamp, head.L1BlockNumber, orm.chainID, head.BaseFeePerGas)
return pkgerrors.Wrap(err, "IdempotentInsertHead failed to insert head")
}
func (orm *DbORM) TrimOldHeads(ctx context.Context, minBlockNumber int64) (err error) {
query := `DELETE FROM evm.heads WHERE evm_chain_id = $1 AND number < $2`
- _, err = orm.db.ExecContext(ctx, query, orm.chainID, minBlockNumber)
+ _, err = orm.ds.ExecContext(ctx, query, orm.chainID, minBlockNumber)
return err
}
func (orm *DbORM) LatestHead(ctx context.Context) (head *evmtypes.Head, err error) {
head = new(evmtypes.Head)
- err = orm.db.GetContext(ctx, head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT 1`, orm.chainID)
+ err = orm.ds.GetContext(ctx, head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT 1`, orm.chainID)
if pkgerrors.Is(err, sql.ErrNoRows) {
return nil, nil
}
@@ -69,14 +69,14 @@ func (orm *DbORM) LatestHead(ctx context.Context) (head *evmtypes.Head, err erro
}
func (orm *DbORM) LatestHeads(ctx context.Context, minBlockNumer int64) (heads []*evmtypes.Head, err error) {
- err = orm.db.SelectContext(ctx, &heads, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 AND number >= $2 ORDER BY number DESC, created_at DESC, id DESC`, orm.chainID, minBlockNumer)
+ err = orm.ds.SelectContext(ctx, &heads, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 AND number >= $2 ORDER BY number DESC, created_at DESC, id DESC`, orm.chainID, minBlockNumer)
err = pkgerrors.Wrap(err, "LatestHeads failed")
return
}
func (orm *DbORM) HeadByHash(ctx context.Context, hash common.Hash) (head *evmtypes.Head, err error) {
head = new(evmtypes.Head)
- err = orm.db.GetContext(ctx, head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 AND hash = $2`, orm.chainID, hash)
+ err = orm.ds.GetContext(ctx, head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 AND hash = $2`, orm.chainID, hash)
if pkgerrors.Is(err, sql.ErrNoRows) {
return nil, nil
}
diff --git a/core/chains/evm/headtracker/types/types.go b/core/chains/evm/headtracker/types/types.go
index 54918588283..1a03f3cec6f 100644
--- a/core/chains/evm/headtracker/types/types.go
+++ b/core/chains/evm/headtracker/types/types.go
@@ -5,22 +5,21 @@ import (
"github.com/ethereum/go-ethereum/common"
- commontypes "github.com/smartcontractkit/chainlink/v2/common/types"
+ "github.com/smartcontractkit/chainlink/v2/common/headtracker"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
// HeadSaver maintains chains persisted in DB. All methods are thread-safe.
type HeadSaver interface {
- commontypes.HeadSaver[*evmtypes.Head, common.Hash]
+ headtracker.HeadSaver[*evmtypes.Head, common.Hash]
// LatestHeadFromDB returns the highest seen head from DB.
LatestHeadFromDB(ctx context.Context) (*evmtypes.Head, error)
}
// Type Alias for EVM Head Tracker Components
type (
- HeadBroadcasterRegistry = commontypes.HeadBroadcasterRegistry[*evmtypes.Head, common.Hash]
- HeadTracker = commontypes.HeadTracker[*evmtypes.Head, common.Hash]
- HeadTrackable = commontypes.HeadTrackable[*evmtypes.Head, common.Hash]
- HeadListener = commontypes.HeadListener[*evmtypes.Head, common.Hash]
- HeadBroadcaster = commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash]
+ HeadTracker = headtracker.HeadTracker[*evmtypes.Head, common.Hash]
+ HeadTrackable = headtracker.HeadTrackable[*evmtypes.Head, common.Hash]
+ HeadListener = headtracker.HeadListener[*evmtypes.Head, common.Hash]
+ HeadBroadcaster = headtracker.HeadBroadcaster[*evmtypes.Head, common.Hash]
)
diff --git a/core/chains/evm/log/broadcaster.go b/core/chains/evm/log/broadcaster.go
index a96474c0f78..148c36148c2 100644
--- a/core/chains/evm/log/broadcaster.go
+++ b/core/chains/evm/log/broadcaster.go
@@ -9,14 +9,13 @@ import (
"sync/atomic"
"time"
- "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
-
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
pkgerrors "github.com/pkg/errors"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
@@ -60,12 +59,10 @@ type (
Register(listener Listener, opts ListenerOpts) (unsubscribe func())
WasAlreadyConsumed(ctx context.Context, lb Broadcast) (bool, error)
- MarkConsumed(ctx context.Context, lb Broadcast) error
-
- // MarkManyConsumed marks all the provided log broadcasts as consumed.
- MarkManyConsumed(ctx context.Context, lbs []Broadcast) error
+ // ds is optional
+ MarkConsumed(ctx context.Context, ds sqlutil.DataSource, lb Broadcast) error
- // NOTE: WasAlreadyConsumed, MarkConsumed and MarkManyConsumed MUST be used within a single goroutine in order for WasAlreadyConsumed to be accurate
+ // NOTE: WasAlreadyConsumed, and MarkConsumed MUST be used within a single goroutine in order for WasAlreadyConsumed to be accurate
}
BroadcasterInTest interface {
@@ -422,12 +419,15 @@ func (b *broadcaster) eventLoop(chRawLogs <-chan types.Log, chErr <-chan error)
debounceResubscribe := time.NewTicker(1 * time.Second)
defer debounceResubscribe.Stop()
+ ctx, cancel := b.chStop.NewCtx()
+ defer cancel()
+
b.logger.Debug("Starting the event loop")
for {
// Replay requests take priority.
select {
case req := <-b.replayChannel:
- b.onReplayRequest(req)
+ b.onReplayRequest(ctx, req)
return true, nil
default:
}
@@ -456,7 +456,7 @@ func (b *broadcaster) eventLoop(chRawLogs <-chan types.Log, chErr <-chan error)
needsResubscribe = b.onChangeSubscriberStatus() || needsResubscribe
case req := <-b.replayChannel:
- b.onReplayRequest(req)
+ b.onReplayRequest(ctx, req)
return true, nil
case <-debounceResubscribe.C:
@@ -480,7 +480,7 @@ func (b *broadcaster) eventLoop(chRawLogs <-chan types.Log, chErr <-chan error)
}
// onReplayRequest clears the pool and sets the block backfill number.
-func (b *broadcaster) onReplayRequest(replayReq replayRequest) {
+func (b *broadcaster) onReplayRequest(ctx context.Context, replayReq replayRequest) {
// notify subscribers that we are about to replay.
for subscriber := range b.registrations.registeredSubs {
if subscriber.opts.ReplayStartedCallback != nil {
@@ -495,11 +495,11 @@ func (b *broadcaster) onReplayRequest(replayReq replayRequest) {
b.backfillBlockNumber.Int64 = replayReq.fromBlock
b.backfillBlockNumber.Valid = true
if replayReq.forceBroadcast {
- ctx, cancel := b.chStop.CtxCancel(context.WithTimeout(context.Background(), time.Minute))
- ctx = sqlutil.WithoutDefaultTimeout(ctx)
- defer cancel()
// Use a longer timeout in the event that a very large amount of logs need to be marked
- // as consumed.
+ // as unconsumed.
+ var cancel func()
+ ctx, cancel = context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute)
+ defer cancel()
err := b.orm.MarkBroadcastsUnconsumed(ctx, replayReq.fromBlock)
if err != nil {
b.logger.Errorw("Error marking broadcasts as unconsumed",
@@ -694,25 +694,12 @@ func (b *broadcaster) WasAlreadyConsumed(ctx context.Context, lb Broadcast) (boo
}
// MarkConsumed marks the log as having been successfully consumed by the subscriber
-func (b *broadcaster) MarkConsumed(ctx context.Context, lb Broadcast) error {
- return b.orm.MarkBroadcastConsumed(ctx, lb.RawLog().BlockHash, lb.RawLog().BlockNumber, lb.RawLog().Index, lb.JobID())
-}
-
-// MarkManyConsumed marks the logs as having been successfully consumed by the subscriber
-func (b *broadcaster) MarkManyConsumed(ctx context.Context, lbs []Broadcast) (err error) {
- var (
- blockHashes = make([]common.Hash, len(lbs))
- blockNumbers = make([]uint64, len(lbs))
- logIndexes = make([]uint, len(lbs))
- jobIDs = make([]int32, len(lbs))
- )
- for i := range lbs {
- blockHashes[i] = lbs[i].RawLog().BlockHash
- blockNumbers[i] = lbs[i].RawLog().BlockNumber
- logIndexes[i] = lbs[i].RawLog().Index
- jobIDs[i] = lbs[i].JobID()
+func (b *broadcaster) MarkConsumed(ctx context.Context, ds sqlutil.DataSource, lb Broadcast) error {
+ orm := b.orm
+ if ds != nil {
+ orm = orm.WithDataSource(ds)
}
- return b.orm.MarkBroadcastsConsumed(ctx, blockHashes, blockNumbers, logIndexes, jobIDs)
+ return orm.MarkBroadcastConsumed(ctx, lb.RawLog().BlockHash, lb.RawLog().BlockNumber, lb.RawLog().Index, lb.JobID())
}
// test only
@@ -779,10 +766,7 @@ func (n *NullBroadcaster) TrackedAddressesCount() uint32 {
func (n *NullBroadcaster) WasAlreadyConsumed(ctx context.Context, lb Broadcast) (bool, error) {
return false, pkgerrors.New(n.ErrMsg)
}
-func (n *NullBroadcaster) MarkConsumed(ctx context.Context, lb Broadcast) error {
- return pkgerrors.New(n.ErrMsg)
-}
-func (n *NullBroadcaster) MarkManyConsumed(ctx context.Context, lbs []Broadcast) error {
+func (n *NullBroadcaster) MarkConsumed(ctx context.Context, ds sqlutil.DataSource, lb Broadcast) error {
return pkgerrors.New(n.ErrMsg)
}
diff --git a/core/chains/evm/log/helpers_test.go b/core/chains/evm/log/helpers_test.go
index 18f396fab9d..85c2fe783bb 100644
--- a/core/chains/evm/log/helpers_test.go
+++ b/core/chains/evm/log/helpers_test.go
@@ -281,7 +281,7 @@ func (listener *simpleLogListener) SkipMarkingConsumed(skip bool) {
listener.skipMarkingConsumed.Store(skip)
}
-func (listener *simpleLogListener) HandleLog(lb log.Broadcast) {
+func (listener *simpleLogListener) HandleLog(ctx context.Context, lb log.Broadcast) {
listener.received.Lock()
defer listener.received.Unlock()
listener.lggr.Tracef("Listener %v HandleLog for block %v %v received at %v %v", listener.name, lb.RawLog().BlockNumber, lb.RawLog().BlockHash, lb.LatestBlockNumber(), lb.LatestBlockHash())
diff --git a/core/chains/evm/log/integration_test.go b/core/chains/evm/log/integration_test.go
index 4bdb43d9521..fd6b375d80a 100644
--- a/core/chains/evm/log/integration_test.go
+++ b/core/chains/evm/log/integration_test.go
@@ -263,8 +263,6 @@ func TestBroadcaster_BackfillUnconsumedAfterCrash(t *testing.T) {
log2 := blocks.LogOnBlockNum(log2Block, contract2.Address())
logs := []types.Log{log1, log2}
- contract1.On("ParseLog", log1).Return(flux_aggregator_wrapper.FluxAggregatorNewRound{}, nil)
- contract2.On("ParseLog", log2).Return(flux_aggregator_wrapper.FluxAggregatorAnswerUpdated{}, nil)
t.Run("pool two logs from subscription, then shut down", func(t *testing.T) {
helper := newBroadcasterHelper(t, 0, 1, logs, func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].FinalityDepth = ptr[uint32](confs)
@@ -295,6 +293,8 @@ func TestBroadcaster_BackfillUnconsumedAfterCrash(t *testing.T) {
c.EVM[0].FinalityDepth = ptr[uint32](confs)
})
orm := log.NewORM(helper.db, cltest.FixtureChainID)
+ contract1.On("ParseLog", log1).Return(flux_aggregator_wrapper.FluxAggregatorNewRound{}, nil)
+ contract2.On("ParseLog", log2).Return(flux_aggregator_wrapper.FluxAggregatorAnswerUpdated{}, nil)
listener := helper.newLogListenerWithJob("one")
listener.SkipMarkingConsumed(true)
diff --git a/core/chains/evm/log/mocks/broadcaster.go b/core/chains/evm/log/mocks/broadcaster.go
index 26fe1a35101..e5164b56611 100644
--- a/core/chains/evm/log/mocks/broadcaster.go
+++ b/core/chains/evm/log/mocks/broadcaster.go
@@ -8,6 +8,8 @@ import (
log "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log"
mock "github.com/stretchr/testify/mock"
+ sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
+
types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
)
@@ -102,35 +104,17 @@ func (_m *Broadcaster) IsConnected() bool {
return r0
}
-// MarkConsumed provides a mock function with given fields: ctx, lb
-func (_m *Broadcaster) MarkConsumed(ctx context.Context, lb log.Broadcast) error {
- ret := _m.Called(ctx, lb)
+// MarkConsumed provides a mock function with given fields: ctx, ds, lb
+func (_m *Broadcaster) MarkConsumed(ctx context.Context, ds sqlutil.DataSource, lb log.Broadcast) error {
+ ret := _m.Called(ctx, ds, lb)
if len(ret) == 0 {
panic("no return value specified for MarkConsumed")
}
var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, log.Broadcast) error); ok {
- r0 = rf(ctx, lb)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// MarkManyConsumed provides a mock function with given fields: ctx, lbs
-func (_m *Broadcaster) MarkManyConsumed(ctx context.Context, lbs []log.Broadcast) error {
- ret := _m.Called(ctx, lbs)
-
- if len(ret) == 0 {
- panic("no return value specified for MarkManyConsumed")
- }
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, []log.Broadcast) error); ok {
- r0 = rf(ctx, lbs)
+ if rf, ok := ret.Get(0).(func(context.Context, sqlutil.DataSource, log.Broadcast) error); ok {
+ r0 = rf(ctx, ds, lb)
} else {
r0 = ret.Error(0)
}
diff --git a/core/chains/evm/log/orm.go b/core/chains/evm/log/orm.go
index 71c9675d6fd..6e94d3bf8a8 100644
--- a/core/chains/evm/log/orm.go
+++ b/core/chains/evm/log/orm.go
@@ -3,16 +3,13 @@ package log
import (
"context"
"database/sql"
- "fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
- "github.com/jmoiron/sqlx"
pkgerrors "github.com/pkg/errors"
"github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
- "github.com/smartcontractkit/chainlink-common/pkg/utils"
ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
)
@@ -31,8 +28,6 @@ type ORM interface {
WasBroadcastConsumed(ctx context.Context, blockHash common.Hash, logIndex uint, jobID int32) (bool, error)
// MarkBroadcastConsumed marks the log broadcast as consumed by jobID.
MarkBroadcastConsumed(ctx context.Context, blockHash common.Hash, blockNumber uint64, logIndex uint, jobID int32) error
- // MarkBroadcastsConsumed marks the log broadcasts as consumed by jobID.
- MarkBroadcastsConsumed(ctx context.Context, blockHashes []common.Hash, blockNumbers []uint64, logIndexes []uint, jobIDs []int32) error
// MarkBroadcastsUnconsumed marks all log broadcasts from all jobs on or after fromBlock as
// unconsumed.
MarkBroadcastsUnconsumed(ctx context.Context, fromBlock int64) error
@@ -45,20 +40,23 @@ type ORM interface {
// Reinitialize cleans up the database by removing any unconsumed broadcasts, then updating (if necessary) and
// returning the pending minimum block number.
Reinitialize(ctx context.Context) (blockNumber *int64, err error)
+
+ WithDataSource(sqlutil.DataSource) ORM
}
type orm struct {
- db sqlutil.DataSource
+ ds sqlutil.DataSource
evmChainID ubig.Big
}
var _ ORM = (*orm)(nil)
-func NewORM(db sqlutil.DataSource, evmChainID big.Int) *orm {
- return &orm{
- db: db,
- evmChainID: *ubig.New(&evmChainID),
- }
+func NewORM(ds sqlutil.DataSource, evmChainID big.Int) *orm {
+ return &orm{ds, *ubig.New(&evmChainID)}
+}
+
+func (o *orm) WithDataSource(ds sqlutil.DataSource) ORM {
+ return &orm{ds, o.evmChainID}
}
func (o *orm) WasBroadcastConsumed(ctx context.Context, blockHash common.Hash, logIndex uint, jobID int32) (consumed bool, err error) {
@@ -75,7 +73,7 @@ func (o *orm) WasBroadcastConsumed(ctx context.Context, blockHash common.Hash, l
jobID,
o.evmChainID,
}
- err = o.db.GetContext(ctx, &consumed, query, args...)
+ err = o.ds.GetContext(ctx, &consumed, query, args...)
if pkgerrors.Is(err, sql.ErrNoRows) {
return false, nil
}
@@ -90,7 +88,7 @@ func (o *orm) FindBroadcasts(ctx context.Context, fromBlockNum int64, toBlockNum
AND block_number <= $2
AND evm_chain_id = $3
`
- err := o.db.SelectContext(ctx, &broadcasts, query, fromBlockNum, toBlockNum, o.evmChainID)
+ err := o.ds.SelectContext(ctx, &broadcasts, query, fromBlockNum, toBlockNum, o.evmChainID)
if err != nil {
return nil, pkgerrors.Wrap(err, "failed to find log broadcasts")
}
@@ -98,7 +96,7 @@ func (o *orm) FindBroadcasts(ctx context.Context, fromBlockNum int64, toBlockNum
}
func (o *orm) CreateBroadcast(ctx context.Context, blockHash common.Hash, blockNumber uint64, logIndex uint, jobID int32) error {
- _, err := o.db.ExecContext(ctx, `
+ _, err := o.ds.ExecContext(ctx, `
INSERT INTO log_broadcasts (block_hash, block_number, log_index, job_id, created_at, updated_at, consumed, evm_chain_id)
VALUES ($1, $2, $3, $4, NOW(), NOW(), false, $5)
`, blockHash, blockNumber, logIndex, jobID, o.evmChainID)
@@ -106,7 +104,7 @@ func (o *orm) CreateBroadcast(ctx context.Context, blockHash common.Hash, blockN
}
func (o *orm) MarkBroadcastConsumed(ctx context.Context, blockHash common.Hash, blockNumber uint64, logIndex uint, jobID int32) error {
- _, err := o.db.ExecContext(ctx, `
+ _, err := o.ds.ExecContext(ctx, `
INSERT INTO log_broadcasts (block_hash, block_number, log_index, job_id, created_at, updated_at, consumed, evm_chain_id)
VALUES ($1, $2, $3, $4, NOW(), NOW(), true, $5)
ON CONFLICT (job_id, block_hash, log_index, evm_chain_id) DO UPDATE
@@ -115,45 +113,9 @@ func (o *orm) MarkBroadcastConsumed(ctx context.Context, blockHash common.Hash,
return pkgerrors.Wrap(err, "failed to mark log broadcast as consumed")
}
-// MarkBroadcastsConsumed marks many broadcasts as consumed.
-// The lengths of all the provided slices must be equal, otherwise an error is returned.
-func (o *orm) MarkBroadcastsConsumed(ctx context.Context, blockHashes []common.Hash, blockNumbers []uint64, logIndexes []uint, jobIDs []int32) error {
- if !utils.AllEqual(len(blockHashes), len(blockNumbers), len(logIndexes), len(jobIDs)) {
- return fmt.Errorf("all arg slice lengths must be equal, got: %d %d %d %d",
- len(blockHashes), len(blockNumbers), len(logIndexes), len(jobIDs),
- )
- }
-
- type input struct {
- BlockHash common.Hash `db:"blockHash"`
- BlockNumber uint64 `db:"blockNumber"`
- LogIndex uint `db:"logIndex"`
- JobID int32 `db:"jobID"`
- ChainID ubig.Big `db:"chainID"`
- }
- inputs := make([]input, len(blockHashes))
- query := `
-INSERT INTO log_broadcasts (block_hash, block_number, log_index, job_id, created_at, updated_at, consumed, evm_chain_id)
-VALUES (:blockHash, :blockNumber, :logIndex, :jobID, NOW(), NOW(), true, :chainID)
-ON CONFLICT (job_id, block_hash, log_index, evm_chain_id) DO UPDATE
-SET consumed = true, updated_at = NOW();
- `
- for i := range blockHashes {
- inputs[i] = input{
- BlockHash: blockHashes[i],
- BlockNumber: blockNumbers[i],
- LogIndex: logIndexes[i],
- JobID: jobIDs[i],
- ChainID: o.evmChainID,
- }
- }
- _, err := o.db.(*sqlx.DB).NamedExecContext(ctx, query, inputs)
- return pkgerrors.Wrap(err, "mark broadcasts consumed")
-}
-
// MarkBroadcastsUnconsumed implements the ORM interface.
func (o *orm) MarkBroadcastsUnconsumed(ctx context.Context, fromBlock int64) error {
- _, err := o.db.ExecContext(ctx, `
+ _, err := o.ds.ExecContext(ctx, `
UPDATE log_broadcasts
SET consumed = false
WHERE block_number >= $1
@@ -193,7 +155,7 @@ func (o *orm) Reinitialize(ctx context.Context) (*int64, error) {
}
func (o *orm) SetPendingMinBlock(ctx context.Context, blockNumber *int64) error {
- _, err := o.db.ExecContext(ctx, `
+ _, err := o.ds.ExecContext(ctx, `
INSERT INTO log_broadcasts_pending (evm_chain_id, block_number, created_at, updated_at) VALUES ($1, $2, NOW(), NOW())
ON CONFLICT (evm_chain_id) DO UPDATE SET block_number = $3, updated_at = NOW()
`, o.evmChainID, blockNumber, blockNumber)
@@ -202,7 +164,7 @@ func (o *orm) SetPendingMinBlock(ctx context.Context, blockNumber *int64) error
func (o *orm) GetPendingMinBlock(ctx context.Context) (*int64, error) {
var blockNumber *int64
- err := o.db.GetContext(ctx, &blockNumber, `
+ err := o.ds.GetContext(ctx, &blockNumber, `
SELECT block_number FROM log_broadcasts_pending WHERE evm_chain_id = $1
`, o.evmChainID)
if pkgerrors.Is(err, sql.ErrNoRows) {
@@ -215,7 +177,7 @@ func (o *orm) GetPendingMinBlock(ctx context.Context) (*int64, error) {
func (o *orm) getUnconsumedMinBlock(ctx context.Context) (*int64, error) {
var blockNumber *int64
- err := o.db.GetContext(ctx, &blockNumber, `
+ err := o.ds.GetContext(ctx, &blockNumber, `
SELECT min(block_number) FROM log_broadcasts
WHERE evm_chain_id = $1
AND consumed = false
@@ -230,7 +192,7 @@ func (o *orm) getUnconsumedMinBlock(ctx context.Context) (*int64, error) {
}
func (o *orm) removeUnconsumed(ctx context.Context) error {
- _, err := o.db.ExecContext(ctx, `
+ _, err := o.ds.ExecContext(ctx, `
DELETE FROM log_broadcasts
WHERE evm_chain_id = $1
AND consumed = false
diff --git a/core/chains/evm/log/orm_test.go b/core/chains/evm/log/orm_test.go
index ba9509d4518..1a6d927cd50 100644
--- a/core/chains/evm/log/orm_test.go
+++ b/core/chains/evm/log/orm_test.go
@@ -21,7 +21,6 @@ func TestORM_broadcasts(t *testing.T) {
db := pgtest.NewSqlxDB(t)
cfg := configtest.NewGeneralConfig(t, nil)
ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
- ctx := testutils.Context(t)
orm := log.NewORM(db, cltest.FixtureChainID)
@@ -44,12 +43,12 @@ func TestORM_broadcasts(t *testing.T) {
require.Zero(t, rowsAffected)
t.Run("WasBroadcastConsumed_DNE", func(t *testing.T) {
- _, err := orm.WasBroadcastConsumed(ctx, rawLog.BlockHash, rawLog.Index, listener.JobID())
+ _, err := orm.WasBroadcastConsumed(testutils.Context(t), rawLog.BlockHash, rawLog.Index, listener.JobID())
require.NoError(t, err)
})
require.True(t, t.Run("CreateBroadcast", func(t *testing.T) {
- err := orm.CreateBroadcast(ctx, rawLog.BlockHash, rawLog.BlockNumber, rawLog.Index, listener.JobID())
+ err := orm.CreateBroadcast(testutils.Context(t), rawLog.BlockHash, rawLog.BlockNumber, rawLog.Index, listener.JobID())
require.NoError(t, err)
var consumed null.Bool
@@ -59,13 +58,13 @@ func TestORM_broadcasts(t *testing.T) {
}))
t.Run("WasBroadcastConsumed_false", func(t *testing.T) {
- was, err := orm.WasBroadcastConsumed(ctx, rawLog.BlockHash, rawLog.Index, listener.JobID())
+ was, err := orm.WasBroadcastConsumed(testutils.Context(t), rawLog.BlockHash, rawLog.Index, listener.JobID())
require.NoError(t, err)
require.False(t, was)
})
require.True(t, t.Run("MarkBroadcastConsumed", func(t *testing.T) {
- err := orm.MarkBroadcastConsumed(ctx, rawLog.BlockHash, rawLog.BlockNumber, rawLog.Index, listener.JobID())
+ err := orm.MarkBroadcastConsumed(testutils.Context(t), rawLog.BlockHash, rawLog.BlockNumber, rawLog.Index, listener.JobID())
require.NoError(t, err)
var consumed null.Bool
@@ -74,66 +73,17 @@ func TestORM_broadcasts(t *testing.T) {
require.Equal(t, null.BoolFrom(true), consumed)
}))
- t.Run("MarkBroadcastsConsumed Success", func(t *testing.T) {
- var (
- err error
- blockHashes []common.Hash
- blockNumbers []uint64
- logIndexes []uint
- jobIDs []int32
- )
- for i := 0; i < 3; i++ {
- l := cltest.RandomLog(t)
- err = orm.CreateBroadcast(ctx, l.BlockHash, l.BlockNumber, l.Index, listener.JobID())
- require.NoError(t, err)
- blockHashes = append(blockHashes, l.BlockHash)
- blockNumbers = append(blockNumbers, l.BlockNumber)
- logIndexes = append(logIndexes, l.Index)
- jobIDs = append(jobIDs, listener.JobID())
-
- }
- err = orm.MarkBroadcastsConsumed(ctx, blockHashes, blockNumbers, logIndexes, jobIDs)
- require.NoError(t, err)
-
- for i := range blockHashes {
- was, err := orm.WasBroadcastConsumed(ctx, blockHashes[i], logIndexes[i], jobIDs[i])
- require.NoError(t, err)
- require.True(t, was)
- }
- })
-
- t.Run("MarkBroadcastsConsumed Failure", func(t *testing.T) {
- var (
- err error
- blockHashes []common.Hash
- blockNumbers []uint64
- logIndexes []uint
- jobIDs []int32
- )
- for i := 0; i < 5; i++ {
- l := cltest.RandomLog(t)
- err = orm.CreateBroadcast(ctx, l.BlockHash, l.BlockNumber, l.Index, listener.JobID())
- require.NoError(t, err)
- blockHashes = append(blockHashes, l.BlockHash)
- blockNumbers = append(blockNumbers, l.BlockNumber)
- logIndexes = append(logIndexes, l.Index)
- jobIDs = append(jobIDs, listener.JobID())
- }
- err = orm.MarkBroadcastsConsumed(ctx, blockHashes[:len(blockHashes)-2], blockNumbers, logIndexes, jobIDs)
- require.Error(t, err)
- })
-
t.Run("WasBroadcastConsumed_true", func(t *testing.T) {
- was, err := orm.WasBroadcastConsumed(ctx, rawLog.BlockHash, rawLog.Index, listener.JobID())
+ was, err := orm.WasBroadcastConsumed(testutils.Context(t), rawLog.BlockHash, rawLog.Index, listener.JobID())
require.NoError(t, err)
require.True(t, was)
})
}
func TestORM_pending(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
orm := log.NewORM(db, cltest.FixtureChainID)
- ctx := testutils.Context(t)
num, err := orm.GetPendingMinBlock(ctx)
require.NoError(t, err)
@@ -156,9 +106,9 @@ func TestORM_pending(t *testing.T) {
}
func TestORM_MarkUnconsumed(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
cfg := configtest.NewGeneralConfig(t, nil)
- ctx := testutils.Context(t)
ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
orm := log.NewORM(db, cltest.FixtureChainID)
@@ -256,8 +206,8 @@ func TestORM_Reinitialize(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
db := pgtest.NewSqlxDB(t)
- orm := log.NewORM(db, cltest.FixtureChainID)
ctx := testutils.Context(t)
+ orm := log.NewORM(db, cltest.FixtureChainID)
jobID := cltest.MustInsertV2JobSpec(t, db, common.BigToAddress(big.NewInt(rand.Int63()))).ID
diff --git a/core/chains/evm/log/registrations.go b/core/chains/evm/log/registrations.go
index b56d3f4aaaa..c82fee43b6e 100644
--- a/core/chains/evm/log/registrations.go
+++ b/core/chains/evm/log/registrations.go
@@ -62,7 +62,7 @@ type (
// The Listener responds to log events through HandleLog.
Listener interface {
- HandleLog(b Broadcast)
+ HandleLog(ctx context.Context, b Broadcast)
JobID() int32
}
@@ -240,6 +240,9 @@ func (r *registrations) sendLogs(ctx context.Context, logsToSend []logsOnBlock,
for _, log := range logsPerBlock.Logs {
handlers.sendLog(ctx, log, latestHead, broadcastsExisting, bc, r.logger)
+ if ctx.Err() != nil {
+ return
+ }
}
}
}
@@ -442,7 +445,7 @@ func (r *handler) sendLog(ctx context.Context, log types.Log, latestHead evmtype
wg.Add(1)
go func() {
defer wg.Done()
- handleLog(&broadcast{
+ handleLog(ctx, &broadcast{
latestBlockNumber,
latestHead.Hash,
latestHead.ReceiptsRoot,
diff --git a/core/chains/evm/log/registrations_test.go b/core/chains/evm/log/registrations_test.go
index 2be01dca2bf..8c0beaa9379 100644
--- a/core/chains/evm/log/registrations_test.go
+++ b/core/chains/evm/log/registrations_test.go
@@ -1,6 +1,7 @@
package log
import (
+ "context"
"testing"
"github.com/ethereum/go-ethereum/common"
@@ -18,8 +19,8 @@ type testListener struct {
jobID int32
}
-func (tl testListener) JobID() int32 { return tl.jobID }
-func (tl testListener) HandleLog(Broadcast) { panic("not implemented") }
+func (tl testListener) JobID() int32 { return tl.jobID }
+func (tl testListener) HandleLog(context.Context, Broadcast) { panic("not implemented") }
func newTestListener(t *testing.T, jobID int32) testListener {
return testListener{jobID}
diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go
index 1e8f1c73b34..070c2c37473 100644
--- a/core/chains/evm/txmgr/broadcaster_test.go
+++ b/core/chains/evm/txmgr/broadcaster_test.go
@@ -64,9 +64,9 @@ func NewTestEthBroadcaster(
lggr := logger.Test(t)
ge := config.EVM().GasEstimator()
- estimator := gas.NewWrappedEvmEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator {
- return gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), ge.BlockHistory(), lggr)
- }, ge.EIP1559DynamicFees(), nil, ge)
+ estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator {
+ return gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), nil, ge.BlockHistory(), lggr, nil)
+ }, ge.EIP1559DynamicFees(), ge)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, keyStore, estimator)
ethBroadcaster := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), config.Database().Listener(), keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync)
@@ -1113,7 +1113,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
t.Run("with erroring callback bails out", func(t *testing.T) {
require.NoError(t, txStore.InsertTx(ctx, &etx))
- fn := func(id uuid.UUID, result interface{}, err error) error {
+ fn := func(ctx context.Context, id uuid.UUID, result interface{}, err error) error {
return errors.New("something exploded in the callback")
}
@@ -1130,7 +1130,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
})
t.Run("calls resume with error", func(t *testing.T) {
- fn := func(id uuid.UUID, result interface{}, err error) error {
+ fn := func(ctx context.Context, id uuid.UUID, result interface{}, err error) error {
require.Equal(t, id, tr.ID)
require.Nil(t, result)
require.Error(t, err)
@@ -1152,9 +1152,9 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
// same as the parent test, but callback is set by ctor
t.Run("callback set by ctor", func(t *testing.T) {
- estimator := gas.NewWrappedEvmEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator {
- return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), evmcfg.EVM().GasEstimator().BlockHistory(), lggr)
- }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), nil, evmcfg.EVM().GasEstimator())
+ estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator {
+ return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), nil, evmcfg.EVM().GasEstimator().BlockHistory(), lggr, nil)
+ }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), evmcfg.EVM().GasEstimator())
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator)
localNextNonce = getLocalNextNonce(t, nonceTracker, fromAddress)
eb2 := txmgr.NewEvmBroadcaster(txStore, txmClient, txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), evmcfg.Database().Listener(), ethKeyStore, txBuilder, lggr, &testCheckerFactory{}, false)
@@ -1738,9 +1738,9 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) {
kst := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
_, fromAddress := cltest.RandomKey{Disabled: false}.MustInsertWithState(t, kst)
- estimator := gas.NewWrappedEvmEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator {
- return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), evmcfg.EVM().GasEstimator().BlockHistory(), lggr)
- }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), nil, evmcfg.EVM().GasEstimator())
+ estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator {
+ return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), nil, evmcfg.EVM().GasEstimator().BlockHistory(), lggr, nil)
+ }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), evmcfg.EVM().GasEstimator())
checkerFactory := &testCheckerFactory{}
ge := evmcfg.EVM().GasEstimator()
diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go
index 80868d448e0..89e88d5a6dc 100644
--- a/core/chains/evm/txmgr/confirmer_test.go
+++ b/core/chains/evm/txmgr/confirmer_test.go
@@ -1,6 +1,7 @@
package txmgr_test
import (
+ "context"
"encoding/json"
"errors"
"fmt"
@@ -126,7 +127,7 @@ func TestEthConfirmer_Lifecycle(t *testing.T) {
newEst := func(logger.Logger) gas.EvmEstimator { return estimator }
lggr := logger.Test(t)
ge := config.EVM().GasEstimator()
- feeEstimator := gas.NewWrappedEvmEstimator(lggr, newEst, ge.EIP1559DynamicFees(), nil, ge)
+ feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, feeEstimator)
ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), config.Database(), ethKeyStore, txBuilder, lggr)
ctx := testutils.Context(t)
@@ -1646,7 +1647,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing
newEst := func(logger.Logger) gas.EvmEstimator { return estimator }
estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint64(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction..."))
ge := ccfg.EVM().GasEstimator()
- feeEstimator := gas.NewWrappedEvmEstimator(lggr, newEst, ge.EIP1559DynamicFees(), nil, ge)
+ feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator)
addresses := []gethCommon.Address{fromAddress}
kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe()
@@ -1694,7 +1695,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing
newEst := func(logger.Logger) gas.EvmEstimator { return estimator }
// Create confirmer with necessary state
ge := ccfg.EVM().GasEstimator()
- feeEstimator := gas.NewWrappedEvmEstimator(lggr, newEst, ge.EIP1559DynamicFees(), nil, ge)
+ feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator)
addresses := []gethCommon.Address{fromAddress}
kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe()
@@ -2966,7 +2967,7 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
pgtest.MustExec(t, db, `SET CONSTRAINTS pipeline_runs_pipeline_spec_id_fkey DEFERRED`)
t.Run("doesn't process task runs that are not suspended (possibly already previously resumed)", func(t *testing.T) {
- ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(uuid.UUID, interface{}, error) error {
+ ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(context.Context, uuid.UUID, interface{}, error) error {
t.Fatal("No value expected")
return nil
})
@@ -2985,7 +2986,7 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
})
t.Run("doesn't process task runs where the receipt is younger than minConfirmations", func(t *testing.T) {
- ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(uuid.UUID, interface{}, error) error {
+ ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(context.Context, uuid.UUID, interface{}, error) error {
t.Fatal("No value expected")
return nil
})
@@ -3006,7 +3007,7 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
ch := make(chan interface{})
nonce := evmtypes.Nonce(3)
var err error
- ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(id uuid.UUID, value interface{}, thisErr error) error {
+ ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(ctx context.Context, id uuid.UUID, value interface{}, thisErr error) error {
err = thisErr
ch <- value
return nil
@@ -3059,7 +3060,7 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
}
ch := make(chan data)
nonce := evmtypes.Nonce(4)
- ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(id uuid.UUID, value interface{}, err error) error {
+ ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(ctx context.Context, id uuid.UUID, value interface{}, err error) error {
ch <- data{value, err}
return nil
})
@@ -3106,7 +3107,7 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
t.Run("does not mark callback complete if callback fails", func(t *testing.T) {
nonce := evmtypes.Nonce(5)
- ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(uuid.UUID, interface{}, error) error {
+ ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, func(context.Context, uuid.UUID, interface{}, error) error {
return errors.New("error")
})
@@ -3132,9 +3133,9 @@ func ptr[T any](t T) *T { return &t }
func newEthConfirmer(t testing.TB, txStore txmgr.EvmTxStore, ethClient client.Client, config evmconfig.ChainScopedConfig, ks keystore.Eth, fn txmgrcommon.ResumeCallback) *txmgr.Confirmer {
lggr := logger.Test(t)
ge := config.EVM().GasEstimator()
- estimator := gas.NewWrappedEvmEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator {
- return gas.NewFixedPriceEstimator(ge, ge.BlockHistory(), lggr)
- }, ge.EIP1559DynamicFees(), nil, ge)
+ estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator {
+ return gas.NewFixedPriceEstimator(ge, nil, ge.BlockHistory(), lggr, nil)
+ }, ge.EIP1559DynamicFees(), ge)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ks, estimator)
ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), config.Database(), ks, txBuilder, lggr)
ec.SetResumeCallback(fn)
diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go
index 55f650e934b..c8e664e8cfe 100644
--- a/core/chains/evm/txmgr/evm_tx_store.go
+++ b/core/chains/evm/txmgr/evm_tx_store.go
@@ -1292,26 +1292,28 @@ func (o *evmTxStore) SaveInProgressAttempt(ctx context.Context, attempt *TxAttem
return nil
}
-func (o *evmTxStore) GetNonFatalTransactions(ctx context.Context, chainID *big.Int) (txes []*Tx, err error) {
+func (o *evmTxStore) GetAbandonedTransactionsByBatch(ctx context.Context, chainID *big.Int, enabledAddrs []common.Address, offset, limit uint) (txes []*Tx, err error) {
var cancel context.CancelFunc
ctx, cancel = o.mergeContexts(ctx)
defer cancel()
- err = o.Transaction(ctx, true, func(orm *evmTxStore) error {
- stmt := `SELECT * FROM evm.txes WHERE state <> 'fatal_error' AND evm_chain_id = $1`
- var dbEtxs []DbEthTx
- if err = orm.q.SelectContext(ctx, &dbEtxs, stmt, chainID.String()); err != nil {
- return fmt.Errorf("failed to load evm.txes: %w", err)
- }
- txes = make([]*Tx, len(dbEtxs))
- dbEthTxsToEvmEthTxPtrs(dbEtxs, txes)
- err = o.LoadTxesAttempts(ctx, txes)
- if err != nil {
- return fmt.Errorf("failed to load evm.txes: %w", err)
- }
- return nil
- })
- return txes, nil
+ var enabledAddrsBytea [][]byte
+ for _, addr := range enabledAddrs {
+ enabledAddrsBytea = append(enabledAddrsBytea, addr[:])
+ }
+
+ // TODO: include confirmed txes https://smartcontract-it.atlassian.net/browse/BCI-2920
+ query := `SELECT * FROM evm.txes WHERE state <> 'fatal_error' AND state <> 'confirmed' AND evm_chain_id = $1
+ AND from_address <> ALL($2) ORDER BY nonce ASC OFFSET $3 LIMIT $4`
+
+ var dbEtxs []DbEthTx
+ if err = o.q.SelectContext(ctx, &dbEtxs, query, chainID.String(), enabledAddrsBytea, offset, limit); err != nil {
+ return nil, fmt.Errorf("failed to load evm.txes: %w", err)
+ }
+ txes = make([]*Tx, len(dbEtxs))
+ dbEthTxsToEvmEthTxPtrs(dbEtxs, txes)
+
+ return txes, err
}
func (o *evmTxStore) GetTxByID(ctx context.Context, id int64) (txe *Tx, err error) {
@@ -1939,7 +1941,7 @@ func (o *evmTxStore) FindTxesWithMetaFieldByReceiptBlockNum(ctx context.Context,
}
// Find transactions loaded with transaction attempts and receipts by transaction IDs and states
-func (o *evmTxStore) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []big.Int, states []txmgrtypes.TxState, chainID *big.Int) (txes []*Tx, err error) {
+func (o *evmTxStore) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []int64, states []txmgrtypes.TxState, chainID *big.Int) (txes []*Tx, err error) {
var cancel context.CancelFunc
ctx, cancel = o.mergeContexts(ctx)
defer cancel()
diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go
index 5bb131862ed..ff5c7ec4abc 100644
--- a/core/chains/evm/txmgr/evm_tx_store_test.go
+++ b/core/chains/evm/txmgr/evm_tx_store_test.go
@@ -7,6 +7,8 @@ import (
"testing"
"time"
+ "github.com/ethereum/go-ethereum/common"
+
commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
@@ -1470,7 +1472,7 @@ func TestORM_GetTxInProgress(t *testing.T) {
})
}
-func TestORM_GetNonFatalTransactions(t *testing.T) {
+func TestORM_GetAbandonedTransactionsByBatch(t *testing.T) {
t.Parallel()
db := pgtest.NewSqlxDB(t)
@@ -1479,9 +1481,19 @@ func TestORM_GetNonFatalTransactions(t *testing.T) {
ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
_, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore)
+ _, enabled := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore)
+ enabledAddrs := []common.Address{enabled}
- t.Run("gets 0 non finalized eth transaction", func(t *testing.T) {
- txes, err := txStore.GetNonFatalTransactions(testutils.Context(t), ethClient.ConfiguredChainID())
+ t.Run("get 0 abandoned transactions", func(t *testing.T) {
+ txes, err := txStore.GetAbandonedTransactionsByBatch(testutils.Context(t), ethClient.ConfiguredChainID(), enabledAddrs, 0, 10)
+ require.NoError(t, err)
+ require.Empty(t, txes)
+ })
+
+ t.Run("do not return enabled addresses", func(t *testing.T) {
+ _ = mustInsertInProgressEthTxWithAttempt(t, txStore, 123, enabled)
+ _ = mustCreateUnstartedGeneratedTx(t, txStore, enabled, ethClient.ConfiguredChainID())
+ txes, err := txStore.GetAbandonedTransactionsByBatch(testutils.Context(t), ethClient.ConfiguredChainID(), enabledAddrs, 0, 10)
require.NoError(t, err)
require.Empty(t, txes)
})
@@ -1490,13 +1502,32 @@ func TestORM_GetNonFatalTransactions(t *testing.T) {
inProgressTx := mustInsertInProgressEthTxWithAttempt(t, txStore, 123, fromAddress)
unstartedTx := mustCreateUnstartedGeneratedTx(t, txStore, fromAddress, ethClient.ConfiguredChainID())
- txes, err := txStore.GetNonFatalTransactions(testutils.Context(t), ethClient.ConfiguredChainID())
+ txes, err := txStore.GetAbandonedTransactionsByBatch(testutils.Context(t), ethClient.ConfiguredChainID(), enabledAddrs, 0, 10)
require.NoError(t, err)
+ require.Len(t, txes, 2)
for _, tx := range txes {
require.True(t, tx.ID == inProgressTx.ID || tx.ID == unstartedTx.ID)
}
})
+
+ t.Run("get batches of transactions", func(t *testing.T) {
+ var batchSize uint = 10
+ numTxes := 55
+ for i := 0; i < numTxes; i++ {
+ _ = mustCreateUnstartedGeneratedTx(t, txStore, fromAddress, ethClient.ConfiguredChainID())
+ }
+
+ allTxes := make([]*txmgr.Tx, 0)
+ err := sqlutil.Batch(func(offset, limit uint) (count uint, err error) {
+ batchTxes, err := txStore.GetAbandonedTransactionsByBatch(testutils.Context(t), ethClient.ConfiguredChainID(), enabledAddrs, offset, limit)
+ require.NoError(t, err)
+ allTxes = append(allTxes, batchTxes...)
+ return uint(len(batchTxes)), nil
+ }, batchSize)
+ require.NoError(t, err)
+ require.Len(t, allTxes, numTxes+2)
+ })
}
func TestORM_GetTxByID(t *testing.T) {
@@ -1841,7 +1872,7 @@ func TestORM_PruneUnstartedTxQueue(t *testing.T) {
t.Run("does not prune if queue has not exceeded capacity-1", func(t *testing.T) {
subject1 := uuid.New()
- strategy1 := txmgrcommon.NewDropOldestStrategy(subject1, uint32(5), cfg.Database().DefaultQueryTimeout())
+ strategy1 := txmgrcommon.NewDropOldestStrategy(subject1, uint32(5))
for i := 0; i < 5; i++ {
mustCreateUnstartedGeneratedTx(t, txStore, fromAddress, &cltest.FixtureChainID, txRequestWithStrategy(strategy1))
}
@@ -1850,7 +1881,7 @@ func TestORM_PruneUnstartedTxQueue(t *testing.T) {
t.Run("prunes if queue has exceeded capacity-1", func(t *testing.T) {
subject2 := uuid.New()
- strategy2 := txmgrcommon.NewDropOldestStrategy(subject2, uint32(3), cfg.Database().DefaultQueryTimeout())
+ strategy2 := txmgrcommon.NewDropOldestStrategy(subject2, uint32(3))
for i := 0; i < 5; i++ {
mustCreateUnstartedGeneratedTx(t, txStore, fromAddress, &cltest.FixtureChainID, txRequestWithStrategy(strategy2))
}
@@ -1858,6 +1889,29 @@ func TestORM_PruneUnstartedTxQueue(t *testing.T) {
})
}
+func TestORM_FindTxesWithAttemptsAndReceiptsByIdsAndState(t *testing.T) {
+ t.Parallel()
+
+ db := pgtest.NewSqlxDB(t)
+ cfg := configtest.NewGeneralConfig(t, nil)
+ txStore := cltest.NewTestTxStore(t, db)
+ ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
+ ctx := testutils.Context(t)
+
+ _, from := cltest.MustInsertRandomKey(t, ethKeyStore)
+
+ tx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 0, 1, from)
+ r := newEthReceipt(4, utils.NewHash(), tx.TxAttempts[0].Hash, 0x1)
+ _, err := txStore.InsertReceipt(ctx, &r.Receipt)
+ require.NoError(t, err)
+
+ txes, err := txStore.FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx, []int64{tx.ID}, []txmgrtypes.TxState{txmgrcommon.TxConfirmed}, testutils.FixtureChainID)
+ require.NoError(t, err)
+ require.Len(t, txes, 1)
+ require.Len(t, txes[0].TxAttempts, 1)
+ require.Len(t, txes[0].TxAttempts[0].Receipts, 1)
+}
+
func AssertCountPerSubject(t *testing.T, txStore txmgr.TestEvmTxStore, expected int64, subject uuid.UUID) {
t.Helper()
count, err := txStore.CountTxesByStateAndSubject(testutils.Context(t), "unstarted", subject)
diff --git a/core/chains/evm/txmgr/mocks/evm_tx_store.go b/core/chains/evm/txmgr/mocks/evm_tx_store.go
index 61c948c1ff4..a05f2a22c60 100644
--- a/core/chains/evm/txmgr/mocks/evm_tx_store.go
+++ b/core/chains/evm/txmgr/mocks/evm_tx_store.go
@@ -672,7 +672,7 @@ func (_m *EvmTxStore) FindTxesPendingCallback(ctx context.Context, blockNum int6
}
// FindTxesWithAttemptsAndReceiptsByIdsAndState provides a mock function with given fields: ctx, ids, states, chainID
-func (_m *EvmTxStore) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []big.Int, states []types.TxState, chainID *big.Int) ([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
+func (_m *EvmTxStore) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Context, ids []int64, states []types.TxState, chainID *big.Int) ([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
ret := _m.Called(ctx, ids, states, chainID)
if len(ret) == 0 {
@@ -681,10 +681,10 @@ func (_m *EvmTxStore) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.C
var r0 []*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, []big.Int, []types.TxState, *big.Int) ([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, []int64, []types.TxState, *big.Int) ([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok {
return rf(ctx, ids, states, chainID)
}
- if rf, ok := ret.Get(0).(func(context.Context, []big.Int, []types.TxState, *big.Int) []*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, []int64, []types.TxState, *big.Int) []*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok {
r0 = rf(ctx, ids, states, chainID)
} else {
if ret.Get(0) != nil {
@@ -692,7 +692,7 @@ func (_m *EvmTxStore) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.C
}
}
- if rf, ok := ret.Get(1).(func(context.Context, []big.Int, []types.TxState, *big.Int) error); ok {
+ if rf, ok := ret.Get(1).(func(context.Context, []int64, []types.TxState, *big.Int) error); ok {
r1 = rf(ctx, ids, states, chainID)
} else {
r1 = ret.Error(1)
@@ -821,29 +821,29 @@ func (_m *EvmTxStore) FindTxsRequiringResubmissionDueToInsufficientFunds(ctx con
return r0, r1
}
-// GetInProgressTxAttempts provides a mock function with given fields: ctx, address, chainID
-func (_m *EvmTxStore) GetInProgressTxAttempts(ctx context.Context, address common.Address, chainID *big.Int) ([]types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
- ret := _m.Called(ctx, address, chainID)
+// GetAbandonedTransactionsByBatch provides a mock function with given fields: ctx, chainID, enabledAddrs, offset, limit
+func (_m *EvmTxStore) GetAbandonedTransactionsByBatch(ctx context.Context, chainID *big.Int, enabledAddrs []common.Address, offset uint, limit uint) ([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
+ ret := _m.Called(ctx, chainID, enabledAddrs, offset, limit)
if len(ret) == 0 {
- panic("no return value specified for GetInProgressTxAttempts")
+ panic("no return value specified for GetAbandonedTransactionsByBatch")
}
- var r0 []types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]
+ var r0 []*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) ([]types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok {
- return rf(ctx, address, chainID)
+ if rf, ok := ret.Get(0).(func(context.Context, *big.Int, []common.Address, uint, uint) ([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok {
+ return rf(ctx, chainID, enabledAddrs, offset, limit)
}
- if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) []types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok {
- r0 = rf(ctx, address, chainID)
+ if rf, ok := ret.Get(0).(func(context.Context, *big.Int, []common.Address, uint, uint) []*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok {
+ r0 = rf(ctx, chainID, enabledAddrs, offset, limit)
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).([]types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee])
+ r0 = ret.Get(0).([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee])
}
}
- if rf, ok := ret.Get(1).(func(context.Context, common.Address, *big.Int) error); ok {
- r1 = rf(ctx, address, chainID)
+ if rf, ok := ret.Get(1).(func(context.Context, *big.Int, []common.Address, uint, uint) error); ok {
+ r1 = rf(ctx, chainID, enabledAddrs, offset, limit)
} else {
r1 = ret.Error(1)
}
@@ -851,29 +851,29 @@ func (_m *EvmTxStore) GetInProgressTxAttempts(ctx context.Context, address commo
return r0, r1
}
-// GetNonFatalTransactions provides a mock function with given fields: ctx, chainID
-func (_m *EvmTxStore) GetNonFatalTransactions(ctx context.Context, chainID *big.Int) ([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
- ret := _m.Called(ctx, chainID)
+// GetInProgressTxAttempts provides a mock function with given fields: ctx, address, chainID
+func (_m *EvmTxStore) GetInProgressTxAttempts(ctx context.Context, address common.Address, chainID *big.Int) ([]types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
+ ret := _m.Called(ctx, address, chainID)
if len(ret) == 0 {
- panic("no return value specified for GetNonFatalTransactions")
+ panic("no return value specified for GetInProgressTxAttempts")
}
- var r0 []*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]
+ var r0 []types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, *big.Int) ([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok {
- return rf(ctx, chainID)
+ if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) ([]types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok {
+ return rf(ctx, address, chainID)
}
- if rf, ok := ret.Get(0).(func(context.Context, *big.Int) []*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok {
- r0 = rf(ctx, chainID)
+ if rf, ok := ret.Get(0).(func(context.Context, common.Address, *big.Int) []types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok {
+ r0 = rf(ctx, address, chainID)
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).([]*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee])
+ r0 = ret.Get(0).([]types.TxAttempt[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee])
}
}
- if rf, ok := ret.Get(1).(func(context.Context, *big.Int) error); ok {
- r1 = rf(ctx, chainID)
+ if rf, ok := ret.Get(1).(func(context.Context, common.Address, *big.Int) error); ok {
+ r1 = rf(ctx, address, chainID)
} else {
r1 = ret.Error(1)
}
diff --git a/core/chains/evm/txmgr/strategies_test.go b/core/chains/evm/txmgr/strategies_test.go
index 19f5f197289..d7f4ceaf450 100644
--- a/core/chains/evm/txmgr/strategies_test.go
+++ b/core/chains/evm/txmgr/strategies_test.go
@@ -11,7 +11,6 @@ import (
txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest"
)
func Test_SendEveryStrategy(t *testing.T) {
@@ -28,10 +27,9 @@ func Test_SendEveryStrategy(t *testing.T) {
func Test_DropOldestStrategy_Subject(t *testing.T) {
t.Parallel()
- cfg := configtest.NewGeneralConfig(t, nil)
subject := uuid.New()
- s := txmgrcommon.NewDropOldestStrategy(subject, 1, cfg.Database().DefaultQueryTimeout())
+ s := txmgrcommon.NewDropOldestStrategy(subject, 1)
assert.True(t, s.Subject().Valid)
assert.Equal(t, subject, s.Subject().UUID)
@@ -39,14 +37,12 @@ func Test_DropOldestStrategy_Subject(t *testing.T) {
func Test_DropOldestStrategy_PruneQueue(t *testing.T) {
t.Parallel()
- cfg := configtest.NewGeneralConfig(t, nil)
subject := uuid.New()
queueSize := uint32(2)
- queryTimeout := cfg.Database().DefaultQueryTimeout()
mockTxStore := mocks.NewEvmTxStore(t)
t.Run("calls PrineUnstartedTxQueue for the given subject and queueSize, ignoring fromAddress", func(t *testing.T) {
- strategy1 := txmgrcommon.NewDropOldestStrategy(subject, queueSize, queryTimeout)
+ strategy1 := txmgrcommon.NewDropOldestStrategy(subject, queueSize)
mockTxStore.On("PruneUnstartedTxQueue", mock.Anything, queueSize-1, subject, mock.Anything, mock.Anything).Once().Return([]int64{1, 2}, nil)
ids, err := strategy1.PruneQueue(testutils.Context(t), mockTxStore)
require.NoError(t, err)
diff --git a/core/chains/evm/txmgr/tracker_test.go b/core/chains/evm/txmgr/tracker_test.go
index e95c005dc77..eefd89c69eb 100644
--- a/core/chains/evm/txmgr/tracker_test.go
+++ b/core/chains/evm/txmgr/tracker_test.go
@@ -1,7 +1,6 @@
package txmgr_test
import (
- "context"
"math/big"
"testing"
"time"
@@ -10,6 +9,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"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"
@@ -44,25 +44,23 @@ func containsID(txes []*txmgr.Tx, id int64) bool {
}
func TestEvmTracker_Initialization(t *testing.T) {
- t.Skip("BCI-2638 tracker disabled")
t.Parallel()
tracker, _, _, _ := newTestEvmTrackerSetup(t)
+ ctx := testutils.Context(t)
- err := tracker.Start(context.Background())
- require.NoError(t, err)
+ require.NoError(t, tracker.Start(ctx))
require.True(t, tracker.IsStarted())
t.Run("stop tracker", func(t *testing.T) {
- err := tracker.Close()
- require.NoError(t, err)
+ require.NoError(t, tracker.Close())
require.False(t, tracker.IsStarted())
})
}
func TestEvmTracker_AddressTracking(t *testing.T) {
- t.Skip("BCI-2638 tracker disabled")
t.Parallel()
+ ctx := testutils.Context(t)
t.Run("track abandoned addresses", func(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
@@ -76,33 +74,37 @@ func TestEvmTracker_AddressTracking(t *testing.T) {
_ = mustInsertConfirmedEthTxWithReceipt(t, txStore, confirmedAddr, 123, 1)
_ = mustCreateUnstartedTx(t, txStore, unstartedAddr, cltest.MustGenerateRandomKey(t).Address, []byte{}, 0, big.Int{}, ethClient.ConfiguredChainID())
- err := tracker.Start(context.Background())
+ err := tracker.Start(ctx)
require.NoError(t, err)
defer func(tracker *txmgr.Tracker) {
err = tracker.Close()
require.NoError(t, err)
}(tracker)
+ time.Sleep(waitTime)
addrs := tracker.GetAbandonedAddresses()
require.NotContains(t, addrs, inProgressAddr)
require.NotContains(t, addrs, unstartedAddr)
- require.Contains(t, addrs, confirmedAddr)
require.Contains(t, addrs, unconfirmedAddr)
})
+ /* TODO: finalized tx state https://smartcontract-it.atlassian.net/browse/BCI-2920
t.Run("stop tracking finalized tx", func(t *testing.T) {
- t.Skip("BCI-2638 tracker disabled")
tracker, txStore, _, _ := newTestEvmTrackerSetup(t)
confirmedAddr := cltest.MustGenerateRandomKey(t).Address
_ = mustInsertConfirmedEthTxWithReceipt(t, txStore, confirmedAddr, 123, 1)
- err := tracker.Start(context.Background())
+ err := tracker.Start(ctx)
require.NoError(t, err)
defer func(tracker *txmgr.Tracker) {
err = tracker.Close()
require.NoError(t, err)
}(tracker)
+ // deliver block before minConfirmations
+ tracker.XXXDeliverBlock(1)
+ time.Sleep(waitTime)
+
addrs := tracker.GetAbandonedAddresses()
require.Contains(t, addrs, confirmedAddr)
@@ -113,26 +115,12 @@ func TestEvmTracker_AddressTracking(t *testing.T) {
addrs = tracker.GetAbandonedAddresses()
require.NotContains(t, addrs, confirmedAddr)
})
+ */
}
func TestEvmTracker_ExceedingTTL(t *testing.T) {
- t.Skip("BCI-2638 tracker disabled")
t.Parallel()
-
- t.Run("confirmed but unfinalized transaction still tracked", func(t *testing.T) {
- tracker, txStore, _, _ := newTestEvmTrackerSetup(t)
- addr1 := cltest.MustGenerateRandomKey(t).Address
- _ = mustInsertConfirmedEthTxWithReceipt(t, txStore, addr1, 123, 1)
-
- err := tracker.Start(context.Background())
- require.NoError(t, err)
- defer func(tracker *txmgr.Tracker) {
- err = tracker.Close()
- require.NoError(t, err)
- }(tracker)
-
- require.Contains(t, tracker.GetAbandonedAddresses(), addr1)
- })
+ ctx := testutils.Context(t)
t.Run("exceeding ttl", func(t *testing.T) {
tracker, txStore, _, _ := newTestEvmTrackerSetup(t)
@@ -142,17 +130,17 @@ func TestEvmTracker_ExceedingTTL(t *testing.T) {
tx2 := cltest.MustInsertUnconfirmedEthTx(t, txStore, 123, addr2)
tracker.XXXTestSetTTL(time.Nanosecond)
- err := tracker.Start(context.Background())
+ err := tracker.Start(ctx)
require.NoError(t, err)
defer func(tracker *txmgr.Tracker) {
err = tracker.Close()
require.NoError(t, err)
}(tracker)
- time.Sleep(waitTime)
+ time.Sleep(100 * waitTime)
require.NotContains(t, tracker.GetAbandonedAddresses(), addr1, addr2)
- fatalTxes, err := txStore.GetFatalTransactions(context.Background())
+ fatalTxes, err := txStore.GetFatalTransactions(ctx)
require.NoError(t, err)
require.True(t, containsID(fatalTxes, tx1.ID))
require.True(t, containsID(fatalTxes, tx2.ID))
diff --git a/core/chains/evm/types/types.go b/core/chains/evm/types/types.go
index 0112dc80ee3..2a6b5eb0ab4 100644
--- a/core/chains/evm/types/types.go
+++ b/core/chains/evm/types/types.go
@@ -3,7 +3,9 @@ package types
import (
"database/sql/driver"
"encoding/json"
+ "log/slog"
"math/big"
+ "os"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
@@ -18,6 +20,12 @@ import (
ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
)
+func init() {
+ // This is a hack to undo geth's disruption of the std default logger.
+ // To be removed after upgrading geth to v1.13.10.
+ slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, nil)))
+}
+
type Configs interface {
Chains(ids ...string) ([]types.ChainStatus, int, error)
Node(name string) (Node, error)
diff --git a/core/chains/legacyevm/mocks/chain.go b/core/chains/legacyevm/mocks/chain.go
index d8cc4895493..87bdccf1891 100644
--- a/core/chains/legacyevm/mocks/chain.go
+++ b/core/chains/legacyevm/mocks/chain.go
@@ -8,8 +8,6 @@ import (
common "github.com/ethereum/go-ethereum/common"
client "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
- commontypes "github.com/smartcontractkit/chainlink/v2/common/types"
-
config "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
context "context"
@@ -18,6 +16,8 @@ import (
gas "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas"
+ headtracker "github.com/smartcontractkit/chainlink/v2/common/headtracker"
+
log "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log"
logger "github.com/smartcontractkit/chainlink/v2/core/logger"
@@ -165,19 +165,19 @@ func (_m *Chain) GetChainStatus(ctx context.Context) (types.ChainStatus, error)
}
// HeadBroadcaster provides a mock function with given fields:
-func (_m *Chain) HeadBroadcaster() commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash] {
+func (_m *Chain) HeadBroadcaster() headtracker.HeadBroadcaster[*evmtypes.Head, common.Hash] {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for HeadBroadcaster")
}
- var r0 commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash]
- if rf, ok := ret.Get(0).(func() commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash]); ok {
+ var r0 headtracker.HeadBroadcaster[*evmtypes.Head, common.Hash]
+ if rf, ok := ret.Get(0).(func() headtracker.HeadBroadcaster[*evmtypes.Head, common.Hash]); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).(commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash])
+ r0 = ret.Get(0).(headtracker.HeadBroadcaster[*evmtypes.Head, common.Hash])
}
}
@@ -185,19 +185,19 @@ func (_m *Chain) HeadBroadcaster() commontypes.HeadBroadcaster[*evmtypes.Head, c
}
// HeadTracker provides a mock function with given fields:
-func (_m *Chain) HeadTracker() commontypes.HeadTracker[*evmtypes.Head, common.Hash] {
+func (_m *Chain) HeadTracker() headtracker.HeadTracker[*evmtypes.Head, common.Hash] {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for HeadTracker")
}
- var r0 commontypes.HeadTracker[*evmtypes.Head, common.Hash]
- if rf, ok := ret.Get(0).(func() commontypes.HeadTracker[*evmtypes.Head, common.Hash]); ok {
+ var r0 headtracker.HeadTracker[*evmtypes.Head, common.Hash]
+ if rf, ok := ret.Get(0).(func() headtracker.HeadTracker[*evmtypes.Head, common.Hash]); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).(commontypes.HeadTracker[*evmtypes.Head, common.Hash])
+ r0 = ret.Get(0).(headtracker.HeadTracker[*evmtypes.Head, common.Hash])
}
}
diff --git a/core/cmd/admin_commands_test.go b/core/cmd/admin_commands_test.go
index 590a24ce8e2..912c4970f47 100644
--- a/core/cmd/admin_commands_test.go
+++ b/core/cmd/admin_commands_test.go
@@ -16,6 +16,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/cmd"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/sessions"
"github.com/smartcontractkit/chainlink/v2/core/web/presenters"
)
@@ -60,10 +61,11 @@ func TestShell_CreateUser(t *testing.T) {
}
func TestShell_ChangeRole(t *testing.T) {
+ ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
- require.NoError(t, app.AuthenticationProvider().CreateUser(&user))
+ require.NoError(t, app.AuthenticationProvider().CreateUser(ctx, &user))
tests := []struct {
name string
@@ -99,10 +101,11 @@ func TestShell_ChangeRole(t *testing.T) {
}
func TestShell_DeleteUser(t *testing.T) {
+ ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
- require.NoError(t, app.BasicAdminUsersORM().CreateUser(&user))
+ require.NoError(t, app.BasicAdminUsersORM().CreateUser(ctx, &user))
tests := []struct {
name string
@@ -133,10 +136,11 @@ func TestShell_DeleteUser(t *testing.T) {
}
func TestShell_ListUsers(t *testing.T) {
+ ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
- require.NoError(t, app.AuthenticationProvider().CreateUser(&user))
+ require.NoError(t, app.AuthenticationProvider().CreateUser(ctx, &user))
set := flag.NewFlagSet("test", 0)
flagSetApplyFromAction(client.ListUsers, set, "")
diff --git a/core/cmd/bridge_commands_test.go b/core/cmd/bridge_commands_test.go
index fae5d68e678..f05aac52cd9 100644
--- a/core/cmd/bridge_commands_test.go
+++ b/core/cmd/bridge_commands_test.go
@@ -63,6 +63,7 @@ func TestBridgePresenter_RenderTable(t *testing.T) {
func TestShell_IndexBridges(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
client, r := app.NewShellAndRenderer()
@@ -72,7 +73,7 @@ func TestShell_IndexBridges(t *testing.T) {
URL: cltest.WebURL(t, "https://testing.com/bridges"),
Confirmations: 0,
}
- err := app.BridgeORM().CreateBridgeType(bt1)
+ err := app.BridgeORM().CreateBridgeType(ctx, bt1)
require.NoError(t, err)
bt2 := &bridges.BridgeType{
@@ -80,7 +81,7 @@ func TestShell_IndexBridges(t *testing.T) {
URL: cltest.WebURL(t, "https://testing.com/bridges"),
Confirmations: 0,
}
- err = app.BridgeORM().CreateBridgeType(bt2)
+ err = app.BridgeORM().CreateBridgeType(ctx, bt2)
require.NoError(t, err)
require.Nil(t, client.IndexBridges(cltest.EmptyCLIContext()))
@@ -108,7 +109,7 @@ func TestShell_ShowBridge(t *testing.T) {
URL: cltest.WebURL(t, "https://testing.com/bridges"),
Confirmations: 0,
}
- require.NoError(t, app.BridgeORM().CreateBridgeType(bt))
+ require.NoError(t, app.BridgeORM().CreateBridgeType(testutils.Context(t), bt))
set := flag.NewFlagSet("test", 0)
flagSetApplyFromAction(client.ShowBridge, set, "")
@@ -173,7 +174,7 @@ func TestShell_RemoveBridge(t *testing.T) {
URL: cltest.WebURL(t, "https://testing.com/bridges"),
Confirmations: 0,
}
- err := app.BridgeORM().CreateBridgeType(bt)
+ err := app.BridgeORM().CreateBridgeType(testutils.Context(t), bt)
require.NoError(t, err)
set := flag.NewFlagSet("test", 0)
diff --git a/core/cmd/jobs_commands.go b/core/cmd/jobs_commands.go
index 1f9ca33c78e..43a7d72f028 100644
--- a/core/cmd/jobs_commands.go
+++ b/core/cmd/jobs_commands.go
@@ -164,6 +164,10 @@ func (p JobPresenter) FriendlyCreatedAt() string {
if p.GatewaySpec != nil {
return p.GatewaySpec.CreatedAt.Format(time.RFC3339)
}
+ case presenters.WorkflowJobSpec:
+ if p.WorkflowSpec != nil {
+ return p.WorkflowSpec.CreatedAt.Format(time.RFC3339)
+ }
default:
return "unknown"
}
diff --git a/core/cmd/shell.go b/core/cmd/shell.go
index 65fa85fc018..de84ed401a6 100644
--- a/core/cmd/shell.go
+++ b/core/cmd/shell.go
@@ -8,7 +8,6 @@ import (
"encoding/json"
"fmt"
"io"
- "log/slog"
"net"
"net/http"
"net/url"
@@ -57,12 +56,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/plugins"
)
-func init() {
- // hack to undo geth's disruption of the std default logger
- // remove with geth v1.13.10
- slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, nil)))
-}
-
var (
initGlobalsOnce sync.Once
prometheus *ginprom.Prometheus
@@ -255,7 +248,7 @@ func handleNodeVersioning(ctx context.Context, db *sqlx.DB, appLggr logger.Logge
if static.Version != static.Unset {
var appv, dbv *semver.Version
- appv, dbv, err = versioning.CheckVersion(db, appLggr, static.Version)
+ appv, dbv, err = versioning.CheckVersion(ctx, db, appLggr, static.Version)
if err != nil {
// Exit immediately and don't touch the database if the app version is too old
return fmt.Errorf("CheckVersion: %w", err)
@@ -287,7 +280,7 @@ func handleNodeVersioning(ctx context.Context, db *sqlx.DB, appLggr logger.Logge
// Update to latest version
if static.Version != static.Unset {
version := versioning.NewNodeVersion(static.Version)
- if err = verORM.UpsertNodeVersion(version); err != nil {
+ if err = verORM.UpsertNodeVersion(ctx, version); err != nil {
return fmt.Errorf("UpsertNodeVersion: %w", err)
}
}
@@ -797,7 +790,7 @@ func (f *fileSessionRequestBuilder) Build(file string) (sessions.SessionRequest,
// needed to access the API. Does nothing if API user already exists.
type APIInitializer interface {
// Initialize creates a new local Admin user for API access, or does nothing if one exists.
- Initialize(orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error)
+ Initialize(ctx context.Context, orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error)
}
type promptingAPIInitializer struct {
@@ -811,9 +804,9 @@ func NewPromptingAPIInitializer(prompter Prompter) APIInitializer {
}
// Initialize uses the terminal to get credentials that it then saves in the store.
-func (t *promptingAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
+func (t *promptingAPIInitializer) Initialize(ctx context.Context, orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
// Load list of users to determine which to assume, or if a user needs to be created
- dbUsers, err := orm.ListUsers()
+ dbUsers, err := orm.ListUsers(ctx)
if err != nil {
return sessions.User{}, errors.Wrap(err, "Unable to List users for initialization")
}
@@ -833,7 +826,7 @@ func (t *promptingAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lg
lggr.Errorw("Error creating API user", "err", err2)
continue
}
- if err = orm.CreateUser(&user); err != nil {
+ if err = orm.CreateUser(ctx, &user); err != nil {
lggr.Errorf("Error creating API user: ", err, "err")
}
return user, err
@@ -847,7 +840,7 @@ func (t *promptingAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lg
// Otherwise, multiple admin users exist, prompt for which to use
email := t.prompter.Prompt("Enter email of API user account to assume: ")
- user, err := orm.FindUser(email)
+ user, err := orm.FindUser(ctx, email)
if err != nil {
return sessions.User{}, err
@@ -865,14 +858,14 @@ func NewFileAPIInitializer(file string) APIInitializer {
return fileAPIInitializer{file: file}
}
-func (f fileAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
+func (f fileAPIInitializer) Initialize(ctx context.Context, orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
request, err := credentialsFromFile(f.file, lggr)
if err != nil {
return sessions.User{}, err
}
// Load list of users to determine which to assume, or if a user needs to be created
- dbUsers, err := orm.ListUsers()
+ dbUsers, err := orm.ListUsers(ctx)
if err != nil {
return sessions.User{}, errors.Wrap(err, "Unable to List users for initialization")
}
@@ -883,7 +876,7 @@ func (f fileAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr log
if err2 != nil {
return user, errors.Wrap(err2, "failed to instantiate new user")
}
- return user, orm.CreateUser(&user)
+ return user, orm.CreateUser(ctx, &user)
}
// Attempt to contextually return the correct admin user, CLI access here implies admin
@@ -892,7 +885,7 @@ func (f fileAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr log
}
// Otherwise, multiple admin users exist, attempt to load email specified in session request
- user, err := orm.FindUser(request.Email)
+ user, err := orm.FindUser(ctx, request.Email)
if err != nil {
return sessions.User{}, err
}
diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go
index e377a0f1109..ccff1669dca 100644
--- a/core/cmd/shell_local.go
+++ b/core/cmd/shell_local.go
@@ -286,6 +286,7 @@ func (s *Shell) RunNode(c *cli.Context) error {
}
func (s *Shell) runNode(c *cli.Context) error {
+ ctx := s.ctx()
lggr := logger.Sugared(s.Logger.Named("RunNode"))
var pwd, vrfpwd *string
@@ -466,11 +467,11 @@ func (s *Shell) runNode(c *cli.Context) error {
}
var user sessions.User
- if user, err = NewFileAPIInitializer(c.String("api")).Initialize(authProviderORM, lggr); err != nil {
+ if user, err = NewFileAPIInitializer(c.String("api")).Initialize(ctx, authProviderORM, lggr); err != nil {
if !errors.Is(err, ErrNoCredentialFile) {
return errors.Wrap(err, "error creating api initializer")
}
- if user, err = s.FallbackAPIInitializer.Initialize(authProviderORM, lggr); err != nil {
+ if user, err = s.FallbackAPIInitializer.Initialize(ctx, authProviderORM, lggr); err != nil {
if errors.Is(err, ErrorNoAPICredentialsAvailable) {
return errors.WithStack(err)
}
diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go
index 6697aafd1c5..9ca05a51ae6 100644
--- a/core/cmd/shell_local_test.go
+++ b/core/cmd/shell_local_test.go
@@ -82,7 +82,7 @@ func TestShell_RunNodeWithPasswords(t *testing.T) {
})
db := pgtest.NewSqlxDB(t)
keyStore := cltest.NewKeyStore(t, db, cfg.Database())
- authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
+ authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), audit.NoopLogger)
lggr := logger.TestLogger(t)
@@ -175,7 +175,7 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) {
c.Insecure.OCRDevelopmentMode = nil
})
db := pgtest.NewSqlxDB(t)
- authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
+ authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), audit.NoopLogger)
// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
diff --git a/core/cmd/shell_remote_test.go b/core/cmd/shell_remote_test.go
index dbd9968daab..0d8d0b7b459 100644
--- a/core/cmd/shell_remote_test.go
+++ b/core/cmd/shell_remote_test.go
@@ -225,7 +225,7 @@ func TestShell_DestroyExternalInitiator(t *testing.T) {
&bridges.ExternalInitiatorRequest{Name: uuid.New().String()},
)
require.NoError(t, err)
- err = app.BridgeORM().CreateExternalInitiator(exi)
+ err = app.BridgeORM().CreateExternalInitiator(testutils.Context(t), exi)
require.NoError(t, err)
set := flag.NewFlagSet("test", 0)
@@ -579,8 +579,8 @@ func TestShell_RunOCRJob_HappyPath(t *testing.T) {
require.NoError(t, app.KeyStore.OCR().Add(cltest.DefaultOCRKey))
- _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
- _, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
+ _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{})
var jb job.Job
ocrspec := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{DS1BridgeName: bridge.Name.String(), DS2BridgeName: bridge2.Name.String()})
@@ -646,11 +646,12 @@ func TestShell_RunOCRJob_JobNotFound(t *testing.T) {
func TestShell_AutoLogin(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
user := cltest.MustRandomUser(t)
- require.NoError(t, app.BasicAdminUsersORM().CreateUser(&user))
+ require.NoError(t, app.BasicAdminUsersORM().CreateUser(ctx, &user))
sr := sessions.SessionRequest{
Email: user.Email,
@@ -674,11 +675,12 @@ func TestShell_AutoLogin(t *testing.T) {
func TestShell_AutoLogin_AuthFails(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
user := cltest.MustRandomUser(t)
- require.NoError(t, app.BasicAdminUsersORM().CreateUser(&user))
+ require.NoError(t, app.BasicAdminUsersORM().CreateUser(ctx, &user))
sr := sessions.SessionRequest{
Email: user.Email,
diff --git a/core/cmd/shell_test.go b/core/cmd/shell_test.go
index d57cfe1f645..d9ac44b46ef 100644
--- a/core/cmd/shell_test.go
+++ b/core/cmd/shell_test.go
@@ -162,9 +162,10 @@ func TestTerminalAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
lggr := logger.TestLogger(t)
- orm := localauth.NewORM(db, time.Minute, lggr, pgtest.NewQConfig(true), audit.NoopLogger)
+ orm := localauth.NewORM(db, time.Minute, lggr, audit.NoopLogger)
mock := &cltest.MockCountingPrompter{T: t, EnteredStrings: test.enteredStrings, NotTerminal: !test.isTerminal}
tai := cmd.NewPromptingAPIInitializer(mock)
@@ -174,14 +175,14 @@ func TestTerminalAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
// create/run with a new admin user
pgtest.MustExec(t, db, "DELETE FROM users;")
- user, err := tai.Initialize(orm, lggr)
+ user, err := tai.Initialize(ctx, orm, lggr)
if test.isError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, len(test.enteredStrings), mock.Count)
- persistedUser, err := orm.FindUser(email)
+ persistedUser, err := orm.FindUser(ctx, email)
assert.NoError(t, err)
assert.Equal(t, user.Email, persistedUser.Email)
@@ -192,10 +193,10 @@ func TestTerminalAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
}
func TestTerminalAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
- cfg := configtest.NewGeneralConfig(t, nil)
lggr := logger.TestLogger(t)
- orm := localauth.NewORM(db, time.Minute, lggr, cfg.Database(), audit.NoopLogger)
+ orm := localauth.NewORM(db, time.Minute, lggr, audit.NoopLogger)
// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
@@ -204,13 +205,13 @@ func TestTerminalAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
require.NoError(t, err)
initialUser := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&initialUser))
+ require.NoError(t, orm.CreateUser(ctx, &initialUser))
mock := &cltest.MockCountingPrompter{T: t}
tai := cmd.NewPromptingAPIInitializer(mock)
// If there is an existing user, and we are in the Terminal prompt, no input prompts required
- user, err := tai.Initialize(orm, lggr)
+ user, err := tai.Initialize(ctx, orm, lggr)
assert.NoError(t, err)
assert.Equal(t, 0, mock.Count)
@@ -230,9 +231,10 @@ func TestFileAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
lggr := logger.TestLogger(t)
- orm := localauth.NewORM(db, time.Minute, lggr, pgtest.NewQConfig(true), audit.NoopLogger)
+ orm := localauth.NewORM(db, time.Minute, lggr, audit.NoopLogger)
// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
@@ -240,13 +242,13 @@ func TestFileAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
pgtest.MustExec(t, db, "DELETE FROM users;")
tfi := cmd.NewFileAPIInitializer(test.file)
- user, err := tfi.Initialize(orm, lggr)
+ user, err := tfi.Initialize(ctx, orm, lggr)
if test.wantError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, cltest.APIEmailAdmin, user.Email)
- persistedUser, err := orm.FindUser(user.Email)
+ persistedUser, err := orm.FindUser(ctx, user.Email)
assert.NoError(t, err)
assert.Equal(t, persistedUser.Email, user.Email)
}
@@ -256,8 +258,7 @@ func TestFileAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
func TestFileAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
db := pgtest.NewSqlxDB(t)
- cfg := configtest.NewGeneralConfig(t, nil)
- orm := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
+ orm := localauth.NewORM(db, time.Minute, logger.TestLogger(t), audit.NoopLogger)
tests := []struct {
name string
@@ -270,9 +271,10 @@ func TestFileAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ ctx := testutils.Context(t)
lggr := logger.TestLogger(t)
tfi := cmd.NewFileAPIInitializer(test.file)
- user, err := tfi.Initialize(orm, lggr)
+ user, err := tfi.Initialize(ctx, orm, lggr)
if test.wantError {
assert.Error(t, err)
} else {
diff --git a/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go b/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go
index cbcbe0fa40f..1f6c763d280 100644
--- a/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go
+++ b/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go
@@ -57,8 +57,8 @@ type AutomationRegistrar23TriggerRegistrationStorage struct {
}
var AutomationRegistrarMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"LINKAddress\",\"type\":\"address\"},{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.InitialTriggerConfig[]\",\"name\":\"triggerConfigs\",\"type\":\"tuple[]\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minRegistrationFees\",\"type\":\"uint256[]\"},{\"internalType\":\"contractIWrappedNative\",\"name\":\"wrappedNativeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"HashMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientPayment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAdminAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBillingToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RequestNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AutoApproveAllowedSenderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"ConfigChanged\",\"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\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"displayName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"RegistrationApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"RegistrationRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"RegistrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"TriggerConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"cancel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"getAutoApproveAllowedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMinimumRegistrationAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"getPendingRequest\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRegistry\",\"outputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"}],\"name\":\"getTriggerRegistrationDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"approvedCount\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.TriggerRegistrationStorage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_WRAPPED_NATIVE_TOKEN\",\"outputs\":[{\"internalType\":\"contractIWrappedNative\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setAutoApproveAllowedSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minBalances\",\"type\":\"uint256[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"setTriggerConfig\",\"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\":\"view\",\"type\":\"function\"}]",
- Bin: "0x60c06040523480156200001157600080fd5b5060405162003187380380620031878339810160408190526200003491620005db565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000183565b5050506001600160a01b03808716608052811660a052620000e18584846200022e565b60005b84518110156200017657620001618582815181106200010757620001076200076d565b6020026020010151600001518683815181106200012857620001286200076d565b6020026020010151602001518784815181106200014957620001496200076d565b6020026020010151604001516200032a60201b60201c565b806200016d8162000783565b915050620000e4565b5050505050505062000804565b336001600160a01b03821603620001dd5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b62000238620003d8565b80518251146200025b57604051630dfe930960e41b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b03851617905560005b8251811015620002fb578181815181106200029857620002986200076d565b602002602001015160046000858481518110620002b957620002b96200076d565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080620002f29062000783565b91505062000279565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b62000334620003d8565b60ff83166000908152600660205260409020805483919060ff19166001836002811115620003665762000366620007ab565b021790555060ff831660009081526006602052604090819020805464ffffffff00191661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390620003cb90859085908590620007c1565b60405180910390a1505050565b6000546001600160a01b03163314620004345760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6001600160a01b03811681146200044c57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200048a576200048a6200044f565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004bb57620004bb6200044f565b604052919050565b60006001600160401b03821115620004df57620004df6200044f565b5060051b60200190565b600082601f830112620004fb57600080fd5b81516020620005146200050e83620004c3565b62000490565b82815260059290921b840181019181810190868411156200053457600080fd5b8286015b848110156200055c5780516200054e8162000436565b835291830191830162000538565b509695505050505050565b600082601f8301126200057957600080fd5b815160206200058c6200050e83620004c3565b82815260059290921b84018101918181019086841115620005ac57600080fd5b8286015b848110156200055c5780518352918301918301620005b0565b8051620005d68162000436565b919050565b60008060008060008060c08789031215620005f557600080fd5b8651620006028162000436565b80965050602080880151620006178162000436565b60408901519096506001600160401b03808211156200063557600080fd5b818a0191508a601f8301126200064a57600080fd5b81516200065b6200050e82620004c3565b81815260609091028301840190848101908d8311156200067a57600080fd5b938501935b8285101562000701576060858f0312156200069a5760008081fd5b620006a462000465565b855160ff81168114620006b75760008081fd5b81528587015160038110620006cc5760008081fd5b81880152604086015163ffffffff81168114620006e95760008081fd5b6040820152825260609490940193908501906200067f565b60608d015190995094505050808311156200071b57600080fd5b620007298b848c01620004e9565b955060808a01519250808311156200074057600080fd5b50506200075089828a0162000567565b9250506200076160a08801620005c9565b90509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060018201620007a457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052602160045260246000fd5b60ff841681526060810160038410620007ea57634e487b7160e01b600052602160045260246000fd5b83602083015263ffffffff83166040830152949350505050565b60805160a05161292c6200085b6000396000818161027b0152818161059501526106280152600081816104a201528181610a9d01528181610b0601528181610f0b0152818161164901526116a0015261292c6000f3fe6080604052600436106101295760003560e01c806388b12d55116100a5578063accb832311610074578063befdae4611610059578063befdae4614610490578063c4d252f5146104c4578063f2fde38b146104e457600080fd5b8063accb832314610450578063b5ff5b411461047057600080fd5b806388b12d55146103085780638da5cb5b146103c2578063a2b1ff94146103ed578063a4c0ed361461043057600080fd5b80635ab1bd53116100fc5780636bf7d75f116100e15780636bf7d75f1461026957806379ba50971461029d5780637e776f7f146102b257600080fd5b80635ab1bd53146101fd57806366ab87f91461024957600080fd5b8063181f5a771461012e578063212d08841461018d5780632ce3a14a146101ba578063367b9b4f146101db575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280601981526020017f4175746f6d6174696f6e52656769737472617220322e332e300000000000000081525081565b6040516101849190611b51565b60405180910390f35b34801561019957600080fd5b506101ad6101a8366004611b81565b610504565b6040516101849190611c06565b6101cd6101c8366004611f1d565b610591565b604051908152602001610184565b3480156101e757600080fd5b506101fb6101f6366004611f60565b6107af565b005b34801561020957600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561025557600080fd5b506101fb610264366004612028565b610841565b34801561027557600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156102a957600080fd5b506101fb610988565b3480156102be57600080fd5b506102f86102cd3660046120fe565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6040519015158152602001610184565b34801561031457600080fd5b5061038961032336600461211b565b60009081526005602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff169290910182905291565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff909116602083015201610184565b3480156103ce57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610224565b3480156103f957600080fd5b506101cd6104083660046120fe565b73ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205490565b34801561043c57600080fd5b506101fb61044b366004612134565b610a85565b34801561045c57600080fd5b506101fb61046b3660046121bd565b610bb3565b34801561047c57600080fd5b506101fb61048b366004612208565b610ce0565b34801561049c57600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156104d057600080fd5b506101fb6104df36600461211b565b610dbf565b3480156104f057600080fd5b506101fb6104ff3660046120fe565b611049565b60408051606080820183526000808352602080840182905283850182905260ff86811683526006909152908490208451928301909452835492939192839116600281111561055457610554611b9c565b600281111561056557610565611b9c565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015292915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260a0015173ffffffffffffffffffffffffffffffffffffffff161480156105f157503415155b156106ac576105ff3461105d565b82602001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561068e57600080fd5b505af11580156106a2573d6000803e3d6000fd5b505050505061079f565b60a082015160208301516040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff909116604482015273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd906064016020604051808303816000875af115801561073e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107629190612251565b61079f576040517f39f1c8d90000000000000000000000000000000000000000000000000000000081523060048201526024015b60405180910390fd5b6107a982336110ff565b92915050565b6107b76114ed565b73ffffffffffffffffffffffffffffffffffffffff821660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356910160405180910390a25050565b6108496114ed565b8051825114610884576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560005b8251811015610959578181815181106108e2576108e261226e565b6020026020010151600460008584815181106109005761090061226e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508080610951906122cc565b9150506108c7565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610796565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610af4576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b0282840184611f1d565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168160a0015173ffffffffffffffffffffffffffffffffffffffff1614610b8d576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6bffffffffffffffffffffffff84166020820152610bab81866110ff565b505050505050565b610bbb6114ed565b60008181526005602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff1691830191909152610c54576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083604051602001610c6791906123b8565b604051602081830303815290604052805190602001209050808314610cb8576040517f3f4d605300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260056020526040812055610cd9610cd38561257f565b82611570565b5050505050565b610ce86114ed565b60ff8316600090815260066020526040902080548391907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115610d3557610d35611b9c565b021790555060ff83166000908152600660205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390610db29085908590859061258b565b60405180910390a1505050565b60008181526005602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff1691830191909152331480610e46575060005473ffffffffffffffffffffffffffffffffffffffff1633145b610e7c576040517f61685c2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16610eca576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260056020908152604080832083905583519184015190517fa9059cbb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169263a9059cbb92610f829260040173ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b6020604051808303816000875af1158015610fa1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc59190612251565b9050806110195781516040517f39f1c8d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610796565b60405183907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a2505050565b6110516114ed565b61105a81611953565b50565b60006bffffffffffffffffffffffff8211156110fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610796565b5090565b60a082015173ffffffffffffffffffffffffffffffffffffffff166000908152600460209081526040822054908401516bffffffffffffffffffffffff161015611175576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604083015173ffffffffffffffffffffffffffffffffffffffff166111c6576040517f05bb467c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460a08401516040517fa538b2eb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063a538b2eb90602401602060405180830381865afa15801561123a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125e9190612251565b611294576040517f1183afea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000836040516020016112a791906125b6565b604051602081830303815290604052805190602001209050836000015173ffffffffffffffffffffffffffffffffffffffff16817f7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b78660c001518760e00151886060015189604001518a608001518b61012001518c61014001518d61010001518e6020015160405161134199989796959493929190612722565b60405180910390a3608084015160ff908116600090815260066020526040808220815160608101909252805492936113c493839116600281111561138757611387611b9c565b600281111561139857611398611b9c565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015285611a48565b1561142c57608085015160ff166000908152600660205260409020805465010000000000900463ffffffff169060056113fc836127dd565b91906101000a81548163ffffffff021916908363ffffffff160217905550506114258583611570565b90506114e5565b60208581015160008481526005909252604082205461147191907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16612800565b6040805180820182528882015173ffffffffffffffffffffffffffffffffffffffff90811682526bffffffffffffffffffffffff9384166020808401918252600089815260059091529390932091519251909316740100000000000000000000000000000000000000000291909216179055505b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461156e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610796565b565b60025482516060840151604080860151608087015160a08801516101008901516101208a01516101408b015195517fc62cf68400000000000000000000000000000000000000000000000000000000815260009973ffffffffffffffffffffffffffffffffffffffff16988a988a9863c62cf684986116009893979296909593949293909290919060040161282c565b6020604051808303816000875af115801561161f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164391906128ba565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168660a0015173ffffffffffffffffffffffffffffffffffffffff160361176a577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea0848860200151856040516020016116f391815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611720939291906128d3565b6020604051808303816000875af115801561173f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117639190612251565b90506118be565b60a086015160208701516040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301526bffffffffffffffffffffffff909216602482015291169063095ea7b3906044016020604051808303816000875af11580156117f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181b9190612251565b905080156118be5760208601516040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff909116602482015273ffffffffffffffffffffffffffffffffffffffff84169063948108f790604401600060405180830381600087803b1580156118a557600080fd5b505af11580156118b9573d6000803e3d6000fd5b505050505b8061190d576040517f39f1c8d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610796565b81857fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b8860c001516040516119429190611b51565b60405180910390a350949350505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036119d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610796565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008083516002811115611a5e57611a5e611b9c565b03611a6b575060006107a9565b600183516002811115611a8057611a80611b9c565b148015611ab3575073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205460ff16155b15611ac0575060006107a9565b826020015163ffffffff16836040015163ffffffff161015611ae4575060016107a9565b50600092915050565b6000815180845260005b81811015611b1357602081850181015186830182015201611af7565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611b646020830184611aed565b9392505050565b803560ff81168114611b7c57600080fd5b919050565b600060208284031215611b9357600080fd5b611b6482611b6b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611c02577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000606082019050611c19828451611bcb565b602083015163ffffffff8082166020850152806040860151166040850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c9257611c92611c3f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cdf57611cdf611c3f565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461105a57600080fd5b8035611b7c81611ce7565b80356bffffffffffffffffffffffff81168114611b7c57600080fd5b803563ffffffff81168114611b7c57600080fd5b600082601f830112611d5557600080fd5b813567ffffffffffffffff811115611d6f57611d6f611c3f565b611da060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611c98565b818152846020838601011115611db557600080fd5b816020850160208301376000918101602001919091529392505050565b60006101608284031215611de557600080fd5b611ded611c6e565b9050611df882611d09565b8152611e0660208301611d14565b6020820152611e1760408301611d09565b6040820152611e2860608301611d30565b6060820152611e3960808301611b6b565b6080820152611e4a60a08301611d09565b60a082015260c082013567ffffffffffffffff80821115611e6a57600080fd5b611e7685838601611d44565b60c084015260e0840135915080821115611e8f57600080fd5b611e9b85838601611d44565b60e084015261010091508184013581811115611eb657600080fd5b611ec286828701611d44565b838501525061012091508184013581811115611edd57600080fd5b611ee986828701611d44565b838501525061014091508184013581811115611f0457600080fd5b611f1086828701611d44565b8385015250505092915050565b600060208284031215611f2f57600080fd5b813567ffffffffffffffff811115611f4657600080fd5b6114e584828501611dd2565b801515811461105a57600080fd5b60008060408385031215611f7357600080fd5b8235611f7e81611ce7565b91506020830135611f8e81611f52565b809150509250929050565b600067ffffffffffffffff821115611fb357611fb3611c3f565b5060051b60200190565b600082601f830112611fce57600080fd5b81356020611fe3611fde83611f99565b611c98565b82815260059290921b8401810191818101908684111561200257600080fd5b8286015b8481101561201d5780358352918301918301612006565b509695505050505050565b60008060006060848603121561203d57600080fd5b833561204881611ce7565b925060208481013567ffffffffffffffff8082111561206657600080fd5b818701915087601f83011261207a57600080fd5b8135612088611fde82611f99565b81815260059190911b8301840190848101908a8311156120a757600080fd5b938501935b828510156120ce5784356120bf81611ce7565b825293850193908501906120ac565b9650505060408701359250808311156120e657600080fd5b50506120f486828701611fbd565b9150509250925092565b60006020828403121561211057600080fd5b8135611b6481611ce7565b60006020828403121561212d57600080fd5b5035919050565b6000806000806060858703121561214a57600080fd5b843561215581611ce7565b935060208501359250604085013567ffffffffffffffff8082111561217957600080fd5b818701915087601f83011261218d57600080fd5b81358181111561219c57600080fd5b8860208285010111156121ae57600080fd5b95989497505060200194505050565b600080604083850312156121d057600080fd5b823567ffffffffffffffff8111156121e757600080fd5b830161016081860312156121fa57600080fd5b946020939093013593505050565b60008060006060848603121561221d57600080fd5b61222684611b6b565b925060208401356003811061223a57600080fd5b915061224860408501611d30565b90509250925092565b60006020828403121561226357600080fd5b8151611b6481611f52565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036122fd576122fd61229d565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261233957600080fd5b830160208101925035905067ffffffffffffffff81111561235957600080fd5b80360382131561236857600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526123e6602082016123cc84611d09565b73ffffffffffffffffffffffffffffffffffffffff169052565b60006123f460208401611d14565b6bffffffffffffffffffffffff811660408401525061241560408401611d09565b73ffffffffffffffffffffffffffffffffffffffff811660608401525061243e60608401611d30565b63ffffffff811660808401525061245760808401611b6b565b60ff811660a08401525061246d60a08401611d09565b73ffffffffffffffffffffffffffffffffffffffff811660c08401525061249760c0840184612304565b6101608060e08601526124af6101808601838561236f565b92506124be60e0870187612304565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06101008188870301818901526124f886868561236f565b9550612506818a018a612304565b955092505061012081888703018189015261252286868561236f565b9550612530818a018a612304565b955092505061014081888703018189015261254c86868561236f565b955061255a818a018a612304565b95509250508087860301838801525061257484848361236f565b979650505050505050565b60006107a93683611dd2565b60ff84168152606081016125a26020830185611bcb565b63ffffffff83166040830152949350505050565b602081526125dd60208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516125fe60408401826bffffffffffffffffffffffff169052565b50604083015173ffffffffffffffffffffffffffffffffffffffff8116606084015250606083015163ffffffff8116608084015250608083015160ff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c08301516101608060e0850152612680610180850183611aed565b915060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06101008187860301818801526126be8584611aed565b9450808801519250506101208187860301818801526126dd8584611aed565b9450808801519250506101408187860301818801526126fc8584611aed565b9088015187820390920184880152935090506127188382611aed565b9695505050505050565b60006101208083526127368184018d611aed565b9050828103602084015261274a818c611aed565b905063ffffffff8a16604084015273ffffffffffffffffffffffffffffffffffffffff8916606084015260ff8816608084015282810360a084015261278f8188611aed565b905082810360c08401526127a38187611aed565b905082810360e08401526127b78186611aed565b9150506bffffffffffffffffffffffff83166101008301529a9950505050505050505050565b600063ffffffff8083168181036127f6576127f661229d565b6001019392505050565b6bffffffffffffffffffffffff8181168382160190808211156128255761282561229d565b5092915050565b600061010073ffffffffffffffffffffffffffffffffffffffff808c16845263ffffffff8b166020850152808a16604085015260ff891660608501528088166080850152508060a084015261288381840187611aed565b905082810360c08401526128978186611aed565b905082810360e08401526128ab8185611aed565b9b9a5050505050505050505050565b6000602082840312156128cc57600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006129166060830184611aed565b9594505050505056fea164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"LINKAddress\",\"type\":\"address\"},{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.InitialTriggerConfig[]\",\"name\":\"triggerConfigs\",\"type\":\"tuple[]\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minRegistrationFees\",\"type\":\"uint256[]\"},{\"internalType\":\"contractIWrappedNative\",\"name\":\"wrappedNativeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HashMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientPayment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAdminAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBillingToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RequestNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AutoApproveAllowedSenderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"ConfigChanged\",\"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\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"displayName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"RegistrationApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"RegistrationRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"RegistrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"TriggerConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"cancel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"getAutoApproveAllowedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMinimumRegistrationAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"getPendingRequest\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRegistry\",\"outputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"}],\"name\":\"getTriggerRegistrationDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"approvedCount\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.TriggerRegistrationStorage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_WRAPPED_NATIVE_TOKEN\",\"outputs\":[{\"internalType\":\"contractIWrappedNative\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setAutoApproveAllowedSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minBalances\",\"type\":\"uint256[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"setTriggerConfig\",\"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\":\"view\",\"type\":\"function\"}]",
+ Bin: "0x60c06040523480156200001157600080fd5b5060405162003483380380620034838339810160408190526200003491620005db565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000183565b5050506001600160a01b03808716608052811660a052620000e18584846200022e565b60005b84518110156200017657620001618582815181106200010757620001076200076d565b6020026020010151600001518683815181106200012857620001286200076d565b6020026020010151602001518784815181106200014957620001496200076d565b6020026020010151604001516200032a60201b60201c565b806200016d8162000783565b915050620000e4565b5050505050505062000804565b336001600160a01b03821603620001dd5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b62000238620003d8565b80518251146200025b57604051630dfe930960e41b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b03851617905560005b8251811015620002fb578181815181106200029857620002986200076d565b602002602001015160046000858481518110620002b957620002b96200076d565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080620002f29062000783565b91505062000279565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b62000334620003d8565b60ff83166000908152600660205260409020805483919060ff19166001836002811115620003665762000366620007ab565b021790555060ff831660009081526006602052604090819020805464ffffffff00191661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390620003cb90859085908590620007c1565b60405180910390a1505050565b6000546001600160a01b03163314620004345760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6001600160a01b03811681146200044c57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200048a576200048a6200044f565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004bb57620004bb6200044f565b604052919050565b60006001600160401b03821115620004df57620004df6200044f565b5060051b60200190565b600082601f830112620004fb57600080fd5b81516020620005146200050e83620004c3565b62000490565b82815260059290921b840181019181810190868411156200053457600080fd5b8286015b848110156200055c5780516200054e8162000436565b835291830191830162000538565b509695505050505050565b600082601f8301126200057957600080fd5b815160206200058c6200050e83620004c3565b82815260059290921b84018101918181019086841115620005ac57600080fd5b8286015b848110156200055c5780518352918301918301620005b0565b8051620005d68162000436565b919050565b60008060008060008060c08789031215620005f557600080fd5b8651620006028162000436565b80965050602080880151620006178162000436565b60408901519096506001600160401b03808211156200063557600080fd5b818a0191508a601f8301126200064a57600080fd5b81516200065b6200050e82620004c3565b81815260609091028301840190848101908d8311156200067a57600080fd5b938501935b8285101562000701576060858f0312156200069a5760008081fd5b620006a462000465565b855160ff81168114620006b75760008081fd5b81528587015160038110620006cc5760008081fd5b81880152604086015163ffffffff81168114620006e95760008081fd5b6040820152825260609490940193908501906200067f565b60608d015190995094505050808311156200071b57600080fd5b620007298b848c01620004e9565b955060808a01519250808311156200074057600080fd5b50506200075089828a0162000567565b9250506200076160a08801620005c9565b90509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060018201620007a457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052602160045260246000fd5b60ff841681526060810160038410620007ea57634e487b7160e01b600052602160045260246000fd5b83602083015263ffffffff83166040830152949350505050565b60805160a051612c2f620008546000396000818161027b015281816105a601526106390152600081816104b301528181610a0301528181610a6c0152818161168501526116dc0152612c2f6000f3fe6080604052600436106101295760003560e01c806388b12d55116100a5578063accb832311610074578063befdae4611610059578063befdae46146104a1578063c4d252f5146104d5578063f2fde38b146104f557600080fd5b8063accb832314610461578063b5ff5b411461048157600080fd5b806388b12d55146103085780638da5cb5b146103d3578063a2b1ff94146103fe578063a4c0ed361461044157600080fd5b80635ab1bd53116100fc5780636bf7d75f116100e15780636bf7d75f1461026957806379ba50971461029d5780637e776f7f146102b257600080fd5b80635ab1bd53146101fd57806366ab87f91461024957600080fd5b8063181f5a771461012e578063212d08841461018d5780632ce3a14a146101ba578063367b9b4f146101db575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280601981526020017f4175746f6d6174696f6e52656769737472617220322e332e300000000000000081525081565b6040516101849190611e6f565b60405180910390f35b34801561019957600080fd5b506101ad6101a8366004611e9f565b610515565b6040516101849190611f24565b6101cd6101c836600461223b565b6105a2565b604051908152602001610184565b3480156101e757600080fd5b506101fb6101f636600461227e565b610710565b005b34801561020957600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561025557600080fd5b506101fb610264366004612346565b6107a2565b34801561027557600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156102a957600080fd5b506101fb6108e9565b3480156102be57600080fd5b506102f86102cd36600461241c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6040519015158152602001610184565b34801561031457600080fd5b5061039a610323366004612439565b6000908152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff169483018590526001909301549092169301929092529091565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff909116602083015201610184565b3480156103df57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610224565b34801561040a57600080fd5b506101cd61041936600461241c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205490565b34801561044d57600080fd5b506101fb61045c366004612452565b6109eb565b34801561046d57600080fd5b506101fb61047c3660046124db565b610b19565b34801561048d57600080fd5b506101fb61049c366004612526565b610c84565b3480156104ad57600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e157600080fd5b506101fb6104f0366004612439565b610d63565b34801561050157600080fd5b506101fb61051036600461241c565b610f2a565b60408051606080820183526000808352602080840182905283850182905260ff86811683526006909152908490208451928301909452835492939192839116600281111561056557610565611eba565b600281111561057657610576611eba565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015292915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260a0015173ffffffffffffffffffffffffffffffffffffffff1614801561060257503415155b156106bd5761061034610f3e565b82602001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561069f57600080fd5b505af11580156106b3573d6000803e3d6000fd5b5050505050610700565b610700333084602001516bffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff16610fe0909392919063ffffffff16565b61070a82336110c2565b92915050565b610718611529565b73ffffffffffffffffffffffffffffffffffffffff821660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356910160405180910390a25050565b6107aa611529565b80518251146107e5576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560005b82518110156108ba578181815181106108435761084361256f565b6020026020010151600460008584815181106108615761086161256f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806108b2906125cd565b915050610828565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461096f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610a5a576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a688284018461223b565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168160a0015173ffffffffffffffffffffffffffffffffffffffff1614610af3576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6bffffffffffffffffffffffff84166020820152610b1181866110c2565b505050505050565b610b21611529565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290610bcd576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083604051602001610be091906126b9565b604051602081830303815290604052805190602001209050808314610c31576040517f3f4d605300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260056020526040812090815560010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055610c7d610c7785612875565b826115ac565b5050505050565b610c8c611529565b60ff8316600090815260066020526040902080548391907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115610cd957610cd9611eba565b021790555060ff83166000908152600660205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390610d5690859085908590612881565b60405180910390a1505050565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290331480610dfd575060005473ffffffffffffffffffffffffffffffffffffffff1633145b610e33576040517f61685c2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16610e81576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600560209081526040808320928355600190920180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905582519083015191830151610efb9273ffffffffffffffffffffffffffffffffffffffff90911691906bffffffffffffffffffffffff1661198f565b60405182907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a25050565b610f32611529565b610f3b816119ea565b50565b60006bffffffffffffffffffffffff821115610fdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610966565b5090565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526110bc9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611adf565b50505050565b60a082015173ffffffffffffffffffffffffffffffffffffffff166000908152600460209081526040822054908401516bffffffffffffffffffffffff161015611138576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604083015173ffffffffffffffffffffffffffffffffffffffff16611189576040517f05bb467c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460a08401516040517fa538b2eb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063a538b2eb90602401602060405180830381865afa1580156111fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122191906128ac565b611257576040517f1183afea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008360405160200161126a91906128c9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600590935291205490915073ffffffffffffffffffffffffffffffffffffffff16156112fd576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015173ffffffffffffffffffffffffffffffffffffffff16817f7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b78660c001518760e00151886060015189604001518a608001518b61012001518c61014001518d61010001518e6020015160405161137f99989796959493929190612a35565b60405180910390a3608084015160ff908116600090815260066020526040808220815160608101909252805492936114029383911660028111156113c5576113c5611eba565b60028111156113d6576113d6611eba565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015285611beb565b1561146a57608085015160ff166000908152600660205260409020805465010000000000900463ffffffff1690600561143a83612af0565b91906101000a81548163ffffffff021916908363ffffffff1602179055505061146385836115ac565b9050611521565b604080516060810182528682015173ffffffffffffffffffffffffffffffffffffffff90811682526020808901516bffffffffffffffffffffffff90811682850190815260a08b01518416858701908152600089815260059094529590922093519151167401000000000000000000000000000000000000000002908216178255915160019091018054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790555b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610966565b565b60025482516060840151604080860151608087015160a08801516101008901516101208a01516101408b015195517fc62cf68400000000000000000000000000000000000000000000000000000000815260009973ffffffffffffffffffffffffffffffffffffffff16988a988a9863c62cf6849861163c98939792969095939492939092909190600401612b13565b6020604051808303816000875af115801561165b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167f9190612ba1565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168660a0015173ffffffffffffffffffffffffffffffffffffffff16036117a6577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea08488602001518560405160200161172f91815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161175c93929190612bba565b6020604051808303816000875af115801561177b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179f91906128ac565b90506118fa565b60a086015160208701516040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301526bffffffffffffffffffffffff909216602482015291169063095ea7b3906044016020604051808303816000875af1158015611833573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185791906128ac565b905080156118fa5760208601516040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff909116602482015273ffffffffffffffffffffffffffffffffffffffff84169063948108f790604401600060405180830381600087803b1580156118e157600080fd5b505af11580156118f5573d6000803e3d6000fd5b505050505b80611949576040517f39f1c8d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610966565b81857fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b8860c0015160405161197e9190611e6f565b60405180910390a350949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526119e59084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161103a565b505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610966565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611b41826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611c909092919063ffffffff16565b8051909150156119e55780806020019051810190611b5f91906128ac565b6119e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610966565b60008083516002811115611c0157611c01611eba565b03611c0e5750600061070a565b600183516002811115611c2357611c23611eba565b148015611c56575073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205460ff16155b15611c635750600061070a565b826020015163ffffffff16836040015163ffffffff161015611c875750600161070a565b50600092915050565b60606115218484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051611cc49190612c06565b60006040518083038185875af1925050503d8060008114611d01576040519150601f19603f3d011682016040523d82523d6000602084013e611d06565b606091505b5091509150611d1787838387611d22565b979650505050505050565b60608315611db8578251600003611db15773ffffffffffffffffffffffffffffffffffffffff85163b611db1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610966565b5081611521565b6115218383815115611dcd5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109669190611e6f565b60005b83811015611e1c578181015183820152602001611e04565b50506000910152565b60008151808452611e3d816020860160208601611e01565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611e826020830184611e25565b9392505050565b803560ff81168114611e9a57600080fd5b919050565b600060208284031215611eb157600080fd5b611e8282611e89565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611f20577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000606082019050611f37828451611ee9565b602083015163ffffffff8082166020850152806040860151166040850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611fb057611fb0611f5d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611ffd57611ffd611f5d565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f3b57600080fd5b8035611e9a81612005565b80356bffffffffffffffffffffffff81168114611e9a57600080fd5b803563ffffffff81168114611e9a57600080fd5b600082601f83011261207357600080fd5b813567ffffffffffffffff81111561208d5761208d611f5d565b6120be60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fb6565b8181528460208386010111156120d357600080fd5b816020850160208301376000918101602001919091529392505050565b6000610160828403121561210357600080fd5b61210b611f8c565b905061211682612027565b815261212460208301612032565b602082015261213560408301612027565b60408201526121466060830161204e565b606082015261215760808301611e89565b608082015261216860a08301612027565b60a082015260c082013567ffffffffffffffff8082111561218857600080fd5b61219485838601612062565b60c084015260e08401359150808211156121ad57600080fd5b6121b985838601612062565b60e0840152610100915081840135818111156121d457600080fd5b6121e086828701612062565b8385015250610120915081840135818111156121fb57600080fd5b61220786828701612062565b83850152506101409150818401358181111561222257600080fd5b61222e86828701612062565b8385015250505092915050565b60006020828403121561224d57600080fd5b813567ffffffffffffffff81111561226457600080fd5b611521848285016120f0565b8015158114610f3b57600080fd5b6000806040838503121561229157600080fd5b823561229c81612005565b915060208301356122ac81612270565b809150509250929050565b600067ffffffffffffffff8211156122d1576122d1611f5d565b5060051b60200190565b600082601f8301126122ec57600080fd5b813560206123016122fc836122b7565b611fb6565b82815260059290921b8401810191818101908684111561232057600080fd5b8286015b8481101561233b5780358352918301918301612324565b509695505050505050565b60008060006060848603121561235b57600080fd5b833561236681612005565b925060208481013567ffffffffffffffff8082111561238457600080fd5b818701915087601f83011261239857600080fd5b81356123a66122fc826122b7565b81815260059190911b8301840190848101908a8311156123c557600080fd5b938501935b828510156123ec5784356123dd81612005565b825293850193908501906123ca565b96505050604087013592508083111561240457600080fd5b5050612412868287016122db565b9150509250925092565b60006020828403121561242e57600080fd5b8135611e8281612005565b60006020828403121561244b57600080fd5b5035919050565b6000806000806060858703121561246857600080fd5b843561247381612005565b935060208501359250604085013567ffffffffffffffff8082111561249757600080fd5b818701915087601f8301126124ab57600080fd5b8135818111156124ba57600080fd5b8860208285010111156124cc57600080fd5b95989497505060200194505050565b600080604083850312156124ee57600080fd5b823567ffffffffffffffff81111561250557600080fd5b8301610160818603121561251857600080fd5b946020939093013593505050565b60008060006060848603121561253b57600080fd5b61254484611e89565b925060208401356003811061255857600080fd5b91506125666040850161204e565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036125fe576125fe61259e565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261263a57600080fd5b830160208101925035905067ffffffffffffffff81111561265a57600080fd5b80360382131561266957600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526126e7602082016126cd84612027565b73ffffffffffffffffffffffffffffffffffffffff169052565b60006126f560208401612032565b6bffffffffffffffffffffffff811660408401525061271660408401612027565b73ffffffffffffffffffffffffffffffffffffffff811660608401525061273f6060840161204e565b63ffffffff811660808401525061275860808401611e89565b60ff811660a08401525061276e60a08401612027565b73ffffffffffffffffffffffffffffffffffffffff811660c08401525061279860c0840184612605565b6101608060e08601526127b061018086018385612670565b92506127bf60e0870187612605565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06101008188870301818901526127f9868685612670565b9550612807818a018a612605565b9550925050610120818887030181890152612823868685612670565b9550612831818a018a612605565b955092505061014081888703018189015261284d868685612670565b955061285b818a018a612605565b955092505080878603018388015250611d17848483612670565b600061070a36836120f0565b60ff84168152606081016128986020830185611ee9565b63ffffffff83166040830152949350505050565b6000602082840312156128be57600080fd5b8151611e8281612270565b602081526128f060208201835173ffffffffffffffffffffffffffffffffffffffff169052565b6000602083015161291160408401826bffffffffffffffffffffffff169052565b50604083015173ffffffffffffffffffffffffffffffffffffffff8116606084015250606083015163ffffffff8116608084015250608083015160ff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c08301516101608060e0850152612993610180850183611e25565b915060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06101008187860301818801526129d18584611e25565b9450808801519250506101208187860301818801526129f08584611e25565b945080880151925050610140818786030181880152612a0f8584611e25565b908801518782039092018488015293509050612a2b8382611e25565b9695505050505050565b6000610120808352612a498184018d611e25565b90508281036020840152612a5d818c611e25565b905063ffffffff8a16604084015273ffffffffffffffffffffffffffffffffffffffff8916606084015260ff8816608084015282810360a0840152612aa28188611e25565b905082810360c0840152612ab68187611e25565b905082810360e0840152612aca8186611e25565b9150506bffffffffffffffffffffffff83166101008301529a9950505050505050505050565b600063ffffffff808316818103612b0957612b0961259e565b6001019392505050565b600061010073ffffffffffffffffffffffffffffffffffffffff808c16845263ffffffff8b166020850152808a16604085015260ff891660608501528088166080850152508060a0840152612b6a81840187611e25565b905082810360c0840152612b7e8186611e25565b905082810360e0840152612b928185611e25565b9b9a5050505050505050505050565b600060208284031215612bb357600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000612bfd6060830184611e25565b95945050505050565b60008251612c18818460208701611e01565b919091019291505056fea164736f6c6343000813000a",
}
var AutomationRegistrarABI = AutomationRegistrarMetaData.ABI
diff --git a/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go
index f982e6ce11a..891415c7d3a 100644
--- a/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go
+++ b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go
@@ -34,6 +34,7 @@ type AutomationRegistryBase23BillingConfig struct {
GasFeePPB uint32
FlatFeeMilliCents *big.Int
PriceFeed common.Address
+ Decimals uint8
FallbackPrice *big.Int
MinSpend *big.Int
}
@@ -44,8 +45,8 @@ type AutomationRegistryBase23BillingOverrides struct {
}
var AutomationRegistryLogicAMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_3\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_3.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x6101806040523480156200001257600080fd5b50604051620047863803806200478683398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e0516101005161012051610140516101605161407262000714600039600081816088015260de01526000505060005050600081816111c701526114e00152600050506000505060005050600050506140726000f3fe608060405260043610620000865760003560e01c80638e86139b11620000555780638e86139b1462000192578063c62cf68414620001b7578063c804802214620001eb578063f2fde38b14620002105762000086565b8063349e8cca14620000ce57806379ba5097146200012857806385c1b0ba14620001405780638da5cb5b1462000165575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015620000c7573d6000f35b3d6000fd5b005b348015620000db57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156200013557600080fd5b50620000cc62000235565b3480156200014d57600080fd5b50620000cc6200015f36600462002cb6565b62000338565b3480156200017257600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16620000fe565b3480156200019f57600080fd5b50620000cc620001b136600462002d8f565b6200108a565b348015620001c457600080fd5b50620001dc620001d636600462002f4d565b62001412565b6040519081526020016200011f565b348015620001f857600080fd5b50620000cc6200020a36600462003042565b620017bf565b3480156200021d57600080fd5b50620000cc6200022f3660046200305c565b62001c97565b60015473ffffffffffffffffffffffffffffffffffffffff163314620002bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601c602052604090205460ff16600381111562000377576200037762003083565b14158015620003c35750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601c602052604090205460ff166003811115620003c057620003c062003083565b14155b15620003fb576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60165473ffffffffffffffffffffffffffffffffffffffff166200044b576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082900362000487576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290528190819060008667ffffffffffffffff811115620004f157620004f162002dfa565b6040519080825280602002602001820160405280156200051b578160200160208202803683370190505b50905060008767ffffffffffffffff8111156200053c576200053c62002dfa565b604051908082528060200260200182016040528015620005d357816020015b604080516101208101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e0820181905261010082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816200055b5790505b50905060008867ffffffffffffffff811115620005f457620005f462002dfa565b6040519080825280602002602001820160405280156200062957816020015b6060815260200190600190039081620006135790505b50905060008967ffffffffffffffff8111156200064a576200064a62002dfa565b6040519080825280602002602001820160405280156200067f57816020015b6060815260200190600190039081620006695790505b50905060008a67ffffffffffffffff811115620006a057620006a062002dfa565b604051908082528060200260200182016040528015620006d557816020015b6060815260200190600190039081620006bf5790505b50905060005b8b81101562000e62578c8c82818110620006f957620006f9620030b2565b602090810292909201356000818152600484526040808220815161012081018352815460ff8082161515835261010080830490911615159883019890985263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e082015260029091015490911694810194909452909a5091985050819003620008545760008881526004602052604090206002015460c088015173ffffffffffffffffffffffffffffffffffffffff9091169a506bffffffffffffffffffffffff1698505b8973ffffffffffffffffffffffffffffffffffffffff1687610100015173ffffffffffffffffffffffffffffffffffffffff1614620009145773ffffffffffffffffffffffffffffffffffffffff8a16600090815260216020526040902054620008c0908a9062003110565b73ffffffffffffffffffffffffffffffffffffffff8b16600081815260216020526040902091909155620008f6908c8b62001caf565b86610100015199508660c001516bffffffffffffffffffffffff1698505b6200091f8862001d43565b60808701516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200098f57600080fd5b505af1158015620009a4573d6000803e3d6000fd5b5050505086858281518110620009be57620009be620030b2565b60200260200101819052506005600089815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686828151811062000a125762000a12620030b2565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091018201526000898152600790915260409020805462000a519062003126565b80601f016020809104026020016040519081016040528092919081815260200182805462000a7f9062003126565b801562000ad05780601f1062000aa45761010080835404028352916020019162000ad0565b820191906000526020600020905b81548152906001019060200180831162000ab257829003601f168201915b505050505084828151811062000aea5762000aea620030b2565b6020026020010181905250601d6000898152602001908152602001600020805462000b159062003126565b80601f016020809104026020016040519081016040528092919081815260200182805462000b439062003126565b801562000b945780601f1062000b685761010080835404028352916020019162000b94565b820191906000526020600020905b81548152906001019060200180831162000b7657829003601f168201915b505050505083828151811062000bae5762000bae620030b2565b6020026020010181905250601e6000898152602001908152602001600020805462000bd99062003126565b80601f016020809104026020016040519081016040528092919081815260200182805462000c079062003126565b801562000c585780601f1062000c2c5761010080835404028352916020019162000c58565b820191906000526020600020905b81548152906001019060200180831162000c3a57829003601f168201915b505050505082828151811062000c725762000c72620030b2565b602090810291909101810191909152600089815260048252604080822080547fffff0000000000000000000000000000000000000000000000000000000000001681556001810183905560020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600790925290812062000cf89162002c19565b6000888152601d6020526040812062000d119162002c19565b6000888152601e6020526040812062000d2a9162002c19565b600088815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562000d6b60028962001dfa565b5060c0870151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8d16602083015289917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a262000ddd60018d62003110565b810362000e4d5773ffffffffffffffffffffffffffffffffffffffff8a1660009081526021602052604090205462000e17908a9062003110565b73ffffffffffffffffffffffffffffffffffffffff8b1660008181526021602052604090209190915562000e4d908c8b62001caf565b8062000e59816200317b565b915050620006db565b5060008c8c868167ffffffffffffffff81111562000e845762000e8462002dfa565b60405190808252806020026020018201604052801562000eae578160200160208202803683370190505b508988888860405160200162000ecc989796959493929190620033ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282526016547faab9edd6000000000000000000000000000000000000000000000000000000008452915190935073ffffffffffffffffffffffffffffffffffffffff808f1693638e86139b939091169163c71249ab91600491869163aab9edd6918482019160209190819003860181865afa15801562000f7c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000fa291906200348c565b866040518463ffffffff1660e01b815260040162000fc393929190620034b1565b600060405180830381865afa15801562000fe1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052620010299190810190620034d8565b6040518263ffffffff1660e01b81526004016200104791906200354f565b600060405180830381600087803b1580156200106257600080fd5b505af115801562001077573d6000803e3d6000fd5b5050505050505050505050505050505050565b6002336000908152601c602052604090205460ff166003811115620010b357620010b362003083565b14158015620010e957506003336000908152601c602052604090205460ff166003811115620010e657620010e662003083565b14155b1562001121576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001137888a018a62003876565b965096509650965096509650965060005b87518110156200140657600073ffffffffffffffffffffffffffffffffffffffff168782815181106200117f576200117f620030b2565b60200260200101516080015173ffffffffffffffffffffffffffffffffffffffff16036200129357858181518110620011bc57620011bc620030b2565b6020026020010151307f0000000000000000000000000000000000000000000000000000000000000000604051620011f49062002c58565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f0801580156200123e573d6000803e3d6000fd5b50878281518110620012545762001254620030b2565b60200260200101516080019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6200134b888281518110620012ac57620012ac620030b2565b6020026020010151888381518110620012c957620012c9620030b2565b6020026020010151878481518110620012e657620012e6620030b2565b6020026020010151878581518110620013035762001303620030b2565b6020026020010151878681518110620013205762001320620030b2565b60200260200101518787815181106200133d576200133d620030b2565b602002602001015162001e11565b878181518110620013605762001360620030b2565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a718883815181106200139e576200139e620030b2565b602002602001015160c0015133604051620013e99291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620013fd816200317b565b91505062001148565b50505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff163314801590620014465750620014446009336200232e565b155b156200147e576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a163b620014cd576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620014d8876200235e565b905060008a307f00000000000000000000000000000000000000000000000000000000000000006040516200150d9062002c58565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562001557573d6000803e3d6000fd5b50905062001648826040518061012001604052806000151581526020016000151581526020018d63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff1681526020018a73ffffffffffffffffffffffffffffffffffffffff168152508b89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062001e119050565b601680547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690601c6200168083620039a7565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128b8b604051620016f992919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d878760405162001735929190620039cd565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200176f91906200354f565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf485084604051620017a991906200354f565b60405180910390a2509998505050505050505050565b6000818152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915290620018e360005473ffffffffffffffffffffffffffffffffffffffff1690565b61010083015173ffffffffffffffffffffffffffffffffffffffff90811660009081526022602090815260408083206002015460155482517f57e871e70000000000000000000000000000000000000000000000000000000081529251968616331497506bffffffffffffffffffffffff90911695939416926357e871e7926004808401939192918290030181865afa15801562001985573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019ab919062003a1a565b9050836060015163ffffffff16600003620019f2576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606084015163ffffffff9081161462001a37576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215801562001a6a575060008581526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562001aa2576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8262001ab85762001ab560328262003a34565b90505b6000858152600460205260409020805463ffffffff8084166601000000000000027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff9092169190911790915562001b1590600290879062001dfa16565b506000826bffffffffffffffffffffffff168560a001516fffffffffffffffffffffffffffffffff16101562001b885760a085015162001b56908462003a4a565b90508460c001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562001b88575060c08401515b808560c0015162001b9a919062003a4a565b600087815260046020908152604080832060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000006bffffffffffffffffffffffff9687160217905561010089015173ffffffffffffffffffffffffffffffffffffffff168352602190915290205462001c2c9183169062003110565b61010086015173ffffffffffffffffffffffffffffffffffffffff1660009081526021602052604080822092909255905167ffffffffffffffff84169188917f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f7911819190a3505050505050565b62001ca1620025fd565b62001cac8162002682565b50565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905262001d3e90849062002779565b505050565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16331462001da1576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020546601000000000000900463ffffffff9081161462001cac576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062001e0883836200288c565b90505b92915050565b601454760100000000000000000000000000000000000000000000900460ff161562001e69576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60175483517c010000000000000000000000000000000000000000000000000000000090910463ffffffff16101562001ece576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856040015163ffffffff16108062001f145750601654604086015163ffffffff780100000000000000000000000000000000000000000000000090920482169116115b1562001f4c576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562001fb7576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010085015173ffffffffffffffffffffffffffffffffffffffff90811660009081526022602052604090205467010000000000000090041662002027576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846004600088815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160010160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050836005600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826007600088815260200190815260200160002090816200226c919062003ac4565b5060c085015161010086015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020526040902054620022b7916bffffffffffffffffffffffff169062003a34565b61010086015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020908152604080832093909355888252601d905220620022fc838262003ac4565b506000868152601e6020526040902062002317828262003ac4565b506200232560028762002997565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151562001e08565b601554604080517f57e871e70000000000000000000000000000000000000000000000000000000081529051600092839273ffffffffffffffffffffffffffffffffffffffff90911691839183916385df51fd9160019184916357e871e79160048083019260209291908290030181865afa158015620023e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002408919062003a1a565b62002414919062003110565b6040518263ffffffff1660e01b81526004016200243391815260200190565b602060405180830381865afa15801562002451573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002477919062003a1a565b60165460408051602081019390935230908301527c0100000000000000000000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f8110156200258b5783828281518110620025475762002547620030b2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002582816200317b565b91505062002527565b50846001811115620025a157620025a162003083565b60f81b81600f81518110620025ba57620025ba620030b2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350620025f48162003beb565b95945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462002680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620002b3565b565b3373ffffffffffffffffffffffffffffffffffffffff82160362002703576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620002b3565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000620027dd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620029a59092919063ffffffff16565b80519091501562001d3e5780806020019051810190620027fe919062003c2e565b62001d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401620002b3565b6000818152600183016020526040812054801562002985576000620028b360018362003110565b8554909150600090620028c99060019062003110565b905081811462002935576000866000018281548110620028ed57620028ed620030b2565b9060005260206000200154905080876000018481548110620029135762002913620030b2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002949576200294962003c4e565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062001e0b565b600091505062001e0b565b5092915050565b600062001e088383620029be565b6060620029b6848460008562002a10565b949350505050565b600081815260018301602052604081205462002a075750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562001e0b565b50600062001e0b565b60608247101562002aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401620002b3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405162002acf919062003c7d565b60006040518083038185875af1925050503d806000811462002b0e576040519150601f19603f3d011682016040523d82523d6000602084013e62002b13565b606091505b509150915062002b268783838762002b31565b979650505050505050565b6060831562002bcc57825160000362002bc45773ffffffffffffffffffffffffffffffffffffffff85163b62002bc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620002b3565b5081620029b6565b620029b6838381511562002be35781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002b391906200354f565b50805462002c279062003126565b6000825580601f1062002c38575050565b601f01602090049060005260206000209081019062001cac919062002c66565b6103ca8062003c9c83390190565b5b8082111562002c7d576000815560010162002c67565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462001cac57600080fd5b803562002cb18162002c81565b919050565b60008060006040848603121562002ccc57600080fd5b833567ffffffffffffffff8082111562002ce557600080fd5b818601915086601f83011262002cfa57600080fd5b81358181111562002d0a57600080fd5b8760208260051b850101111562002d2057600080fd5b6020928301955093505084013562002d388162002c81565b809150509250925092565b60008083601f84011262002d5657600080fd5b50813567ffffffffffffffff81111562002d6f57600080fd5b60208301915083602082850101111562002d8857600080fd5b9250929050565b6000806020838503121562002da357600080fd5b823567ffffffffffffffff81111562002dbb57600080fd5b62002dc98582860162002d43565b90969095509350505050565b803563ffffffff8116811462002cb157600080fd5b80356002811062002cb157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff8111828210171562002e505762002e5062002dfa565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562002ea05762002ea062002dfa565b604052919050565b600067ffffffffffffffff82111562002ec55762002ec562002dfa565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011262002f0357600080fd5b813562002f1a62002f148262002ea8565b62002e56565b81815284602083860101111562002f3057600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060006101008a8c03121562002f6d57600080fd5b62002f788a62002ca4565b985062002f8860208b0162002dd5565b975062002f9860408b0162002ca4565b965062002fa860608b0162002dea565b955062002fb860808b0162002ca4565b945060a08a013567ffffffffffffffff8082111562002fd657600080fd5b62002fe48d838e0162002d43565b909650945060c08c013591508082111562002ffe57600080fd5b6200300c8d838e0162002ef1565b935060e08c01359150808211156200302357600080fd5b50620030328c828d0162002ef1565b9150509295985092959850929598565b6000602082840312156200305557600080fd5b5035919050565b6000602082840312156200306f57600080fd5b81356200307c8162002c81565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111562001e0b5762001e0b620030e1565b600181811c908216806200313b57607f821691505b60208210810362003175577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620031af57620031af620030e1565b5060010190565b600081518084526020808501945080840160005b838110156200328f5781518051151588528381015115158489015260408082015163ffffffff908116918a01919091526060808301518216908a015260808083015173ffffffffffffffffffffffffffffffffffffffff908116918b019190915260a0808401516fffffffffffffffffffffffffffffffff16908b015260c0808401516bffffffffffffffffffffffff16908b015260e080840151909216918a01919091526101009182015116908801526101209096019590820190600101620031ca565b509495945050505050565b600081518084526020808501945080840160005b838110156200328f57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101620032ae565b60005b83811015620032ff578181015183820152602001620032e5565b50506000910152565b6000815180845262003322816020860160208601620032e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015620033a05782840389526200338d84835162003308565b9885019893509084019060010162003372565b5091979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a1115620033ea57600080fd5b8960051b808c838601378301838103820160208501526200340e8282018b620031b6565b91505082810360408401526200342581896200329a565b905082810360608401526200343b81886200329a565b9050828103608084015262003451818762003354565b905082810360a084015262003467818662003354565b905082810360c08401526200347d818562003354565b9b9a5050505050505050505050565b6000602082840312156200349f57600080fd5b815160ff811681146200307c57600080fd5b60ff8416815260ff83166020820152606060408201526000620025f4606083018462003308565b600060208284031215620034eb57600080fd5b815167ffffffffffffffff8111156200350357600080fd5b8201601f810184136200351557600080fd5b80516200352662002f148262002ea8565b8181528560208385010111156200353c57600080fd5b620025f4826020830160208601620032e2565b60208152600062001e08602083018462003308565b600067ffffffffffffffff82111562003581576200358162002dfa565b5060051b60200190565b600082601f8301126200359d57600080fd5b81356020620035b062002f148362003564565b82815260059290921b84018101918181019086841115620035d057600080fd5b8286015b84811015620035ed5780358352918301918301620035d4565b509695505050505050565b801515811462001cac57600080fd5b803562002cb181620035f8565b80356fffffffffffffffffffffffffffffffff8116811462002cb157600080fd5b80356bffffffffffffffffffffffff8116811462002cb157600080fd5b600082601f8301126200366457600080fd5b813560206200367762002f148362003564565b82815261012092830285018201928282019190878511156200369857600080fd5b8387015b85811015620037725781818a031215620036b65760008081fd5b620036c062002e29565b620036cb8262003607565b8152620036da86830162003607565b868201526040620036ed81840162002dd5565b9082015260606200370083820162002dd5565b9082015260806200371383820162002ca4565b9082015260a06200372683820162003614565b9082015260c06200373983820162003635565b9082015260e06200374c83820162002dd5565b908201526101006200376083820162002ca4565b9082015284529284019281016200369c565b5090979650505050505050565b600082601f8301126200379157600080fd5b81356020620037a462002f148362003564565b82815260059290921b84018101918181019086841115620037c457600080fd5b8286015b84811015620035ed578035620037de8162002c81565b8352918301918301620037c8565b600082601f830112620037fe57600080fd5b813560206200381162002f148362003564565b82815260059290921b840181019181810190868411156200383157600080fd5b8286015b84811015620035ed57803567ffffffffffffffff811115620038575760008081fd5b620038678986838b010162002ef1565b84525091830191830162003835565b600080600080600080600060e0888a0312156200389257600080fd5b873567ffffffffffffffff80821115620038ab57600080fd5b620038b98b838c016200358b565b985060208a0135915080821115620038d057600080fd5b620038de8b838c0162003652565b975060408a0135915080821115620038f557600080fd5b620039038b838c016200377f565b965060608a01359150808211156200391a57600080fd5b620039288b838c016200377f565b955060808a01359150808211156200393f57600080fd5b6200394d8b838c01620037ec565b945060a08a01359150808211156200396457600080fd5b620039728b838c01620037ec565b935060c08a01359150808211156200398957600080fd5b50620039988a828b01620037ec565b91505092959891949750929550565b600063ffffffff808316818103620039c357620039c3620030e1565b6001019392505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60006020828403121562003a2d57600080fd5b5051919050565b8082018082111562001e0b5762001e0b620030e1565b6bffffffffffffffffffffffff828116828216039080821115620029905762002990620030e1565b601f82111562001d3e57600081815260208120601f850160051c8101602086101562003a9b5750805b601f850160051c820191505b8181101562003abc5782815560010162003aa7565b505050505050565b815167ffffffffffffffff81111562003ae15762003ae162002dfa565b62003af98162003af2845462003126565b8462003a72565b602080601f83116001811462003b4f576000841562003b185750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855562003abc565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101562003b9e5788860151825594840194600190910190840162003b7d565b508582101562003bdb57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8051602080830151919081101562003175577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b60006020828403121562003c4157600080fd5b81516200307c81620035f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000825162003c91818460208701620032e2565b919091019291505056fe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_3\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_3.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x6101806040523480156200001257600080fd5b506040516200477c3803806200477c83398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e0516101005161012051610140516101605161406862000714600039600081816088015260de01526000505060005050600081816111bd01526114d60152600050506000505060005050600050506140686000f3fe608060405260043610620000865760003560e01c80638e86139b11620000555780638e86139b1462000192578063c62cf68414620001b7578063c804802214620001eb578063f2fde38b14620002105762000086565b8063349e8cca14620000ce57806379ba5097146200012857806385c1b0ba14620001405780638da5cb5b1462000165575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015620000c7573d6000f35b3d6000fd5b005b348015620000db57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156200013557600080fd5b50620000cc62000235565b3480156200014d57600080fd5b50620000cc6200015f36600462002cac565b62000338565b3480156200017257600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16620000fe565b3480156200019f57600080fd5b50620000cc620001b136600462002d85565b62001080565b348015620001c457600080fd5b50620001dc620001d636600462002f43565b62001408565b6040519081526020016200011f565b348015620001f857600080fd5b50620000cc6200020a36600462003038565b620017b5565b3480156200021d57600080fd5b50620000cc6200022f36600462003052565b62001c8d565b60015473ffffffffffffffffffffffffffffffffffffffff163314620002bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601c602052604090205460ff16600381111562000377576200037762003079565b14158015620003c35750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601c602052604090205460ff166003811115620003c057620003c062003079565b14155b15620003fb576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60165473ffffffffffffffffffffffffffffffffffffffff166200044b576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082900362000487576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290528190819060008667ffffffffffffffff811115620004f157620004f162002df0565b6040519080825280602002602001820160405280156200051b578160200160208202803683370190505b50905060008767ffffffffffffffff8111156200053c576200053c62002df0565b604051908082528060200260200182016040528015620005d357816020015b604080516101208101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e0820181905261010082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816200055b5790505b50905060008867ffffffffffffffff811115620005f457620005f462002df0565b6040519080825280602002602001820160405280156200062957816020015b6060815260200190600190039081620006135790505b50905060008967ffffffffffffffff8111156200064a576200064a62002df0565b6040519080825280602002602001820160405280156200067f57816020015b6060815260200190600190039081620006695790505b50905060008a67ffffffffffffffff811115620006a057620006a062002df0565b604051908082528060200260200182016040528015620006d557816020015b6060815260200190600190039081620006bf5790505b50905060005b8b81101562000def578c8c82818110620006f957620006f9620030a8565b602090810292909201356000818152600484526040808220815161012081018352815460ff8082161515835261010080830490911615159883019890985263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e082015260029091015490911694810194909452909a5091985050819003620008305786610100015199508660c001516bffffffffffffffffffffffff1698505b8973ffffffffffffffffffffffffffffffffffffffff1687610100015173ffffffffffffffffffffffffffffffffffffffff1614620008f55773ffffffffffffffffffffffffffffffffffffffff8a166000908152602160205260409020546200089c908a9062003106565b73ffffffffffffffffffffffffffffffffffffffff8b16600081815260216020526040902091909155620008d2908c8b62001ca5565b86610100015199508660c001516bffffffffffffffffffffffff1698506200091e565b80156200091e5760c08701516200091b906bffffffffffffffffffffffff168a6200311c565b98505b620009298862001d39565b60808701516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200099957600080fd5b505af1158015620009ae573d6000803e3d6000fd5b5050505086858281518110620009c857620009c8620030a8565b60200260200101819052506005600089815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686828151811062000a1c5762000a1c620030a8565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091018201526000898152600790915260409020805462000a5b9062003132565b80601f016020809104026020016040519081016040528092919081815260200182805462000a899062003132565b801562000ada5780601f1062000aae5761010080835404028352916020019162000ada565b820191906000526020600020905b81548152906001019060200180831162000abc57829003601f168201915b505050505084828151811062000af45762000af4620030a8565b6020026020010181905250601d6000898152602001908152602001600020805462000b1f9062003132565b80601f016020809104026020016040519081016040528092919081815260200182805462000b4d9062003132565b801562000b9e5780601f1062000b725761010080835404028352916020019162000b9e565b820191906000526020600020905b81548152906001019060200180831162000b8057829003601f168201915b505050505083828151811062000bb85762000bb8620030a8565b6020026020010181905250601e6000898152602001908152602001600020805462000be39062003132565b80601f016020809104026020016040519081016040528092919081815260200182805462000c119062003132565b801562000c625780601f1062000c365761010080835404028352916020019162000c62565b820191906000526020600020905b81548152906001019060200180831162000c4457829003601f168201915b505050505082828151811062000c7c5762000c7c620030a8565b602090810291909101810191909152600089815260048252604080822080547fffff0000000000000000000000000000000000000000000000000000000000001681556001810183905560020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600790925290812062000d029162002c0f565b6000888152601d6020526040812062000d1b9162002c0f565b6000888152601e6020526040812062000d349162002c0f565b600088815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562000d7560028962001df0565b5060c0870151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8d16602083015289917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062000de68162003187565b915050620006db565b5073ffffffffffffffffffffffffffffffffffffffff891660009081526021602052604090205462000e2390899062003106565b73ffffffffffffffffffffffffffffffffffffffff8a1660008181526021602052604090209190915562000e59908b8a62001ca5565b60008c8c868167ffffffffffffffff81111562000e7a5762000e7a62002df0565b60405190808252806020026020018201604052801562000ea4578160200160208202803683370190505b508988888860405160200162000ec2989796959493929190620033b9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282526016547faab9edd6000000000000000000000000000000000000000000000000000000008452915190935073ffffffffffffffffffffffffffffffffffffffff808f1693638e86139b939091169163c71249ab91600491869163aab9edd6918482019160209190819003860181865afa15801562000f72573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f98919062003498565b866040518463ffffffff1660e01b815260040162000fb993929190620034bd565b600060405180830381865afa15801562000fd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526200101f9190810190620034e4565b6040518263ffffffff1660e01b81526004016200103d91906200355b565b600060405180830381600087803b1580156200105857600080fd5b505af11580156200106d573d6000803e3d6000fd5b5050505050505050505050505050505050565b6002336000908152601c602052604090205460ff166003811115620010a957620010a962003079565b14158015620010df57506003336000908152601c602052604090205460ff166003811115620010dc57620010dc62003079565b14155b1562001117576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080808080806200112d888a018a62003882565b965096509650965096509650965060005b8751811015620013fc57600073ffffffffffffffffffffffffffffffffffffffff16878281518110620011755762001175620030a8565b60200260200101516080015173ffffffffffffffffffffffffffffffffffffffff16036200128957858181518110620011b257620011b2620030a8565b6020026020010151307f0000000000000000000000000000000000000000000000000000000000000000604051620011ea9062002c4e565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562001234573d6000803e3d6000fd5b508782815181106200124a576200124a620030a8565b60200260200101516080019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62001341888281518110620012a257620012a2620030a8565b6020026020010151888381518110620012bf57620012bf620030a8565b6020026020010151878481518110620012dc57620012dc620030a8565b6020026020010151878581518110620012f957620012f9620030a8565b6020026020010151878681518110620013165762001316620030a8565b6020026020010151878781518110620013335762001333620030a8565b602002602001015162001e07565b878181518110620013565762001356620030a8565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620013945762001394620030a8565b602002602001015160c0015133604051620013df9291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620013f38162003187565b9150506200113e565b50505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200143c57506200143a60093362002324565b155b1562001474576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a163b620014c3576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620014ce8762002354565b905060008a307f0000000000000000000000000000000000000000000000000000000000000000604051620015039062002c4e565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f0801580156200154d573d6000803e3d6000fd5b5090506200163e826040518061012001604052806000151581526020016000151581526020018d63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff1681526020018a73ffffffffffffffffffffffffffffffffffffffff168152508b89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062001e079050565b601680547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690601c6200167683620039b3565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128b8b604051620016ef92919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d87876040516200172b929190620039d9565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200176591906200355b565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850846040516200179f91906200355b565b60405180910390a2509998505050505050505050565b6000818152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915290620018d960005473ffffffffffffffffffffffffffffffffffffffff1690565b61010083015173ffffffffffffffffffffffffffffffffffffffff90811660009081526022602090815260408083206002015460155482517f57e871e70000000000000000000000000000000000000000000000000000000081529251968616331497506bffffffffffffffffffffffff90911695939416926357e871e7926004808401939192918290030181865afa1580156200197b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019a1919062003a26565b9050836060015163ffffffff16600003620019e8576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606084015163ffffffff9081161462001a2d576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215801562001a60575060008581526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562001a98576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8262001aae5762001aab6032826200311c565b90505b6000858152600460205260409020805463ffffffff8084166601000000000000027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff9092169190911790915562001b0b90600290879062001df016565b506000826bffffffffffffffffffffffff168560a001516fffffffffffffffffffffffffffffffff16101562001b7e5760a085015162001b4c908462003a40565b90508460c001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562001b7e575060c08401515b808560c0015162001b90919062003a40565b600087815260046020908152604080832060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000006bffffffffffffffffffffffff9687160217905561010089015173ffffffffffffffffffffffffffffffffffffffff168352602190915290205462001c229183169062003106565b61010086015173ffffffffffffffffffffffffffffffffffffffff1660009081526021602052604080822092909255905167ffffffffffffffff84169188917f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f7911819190a3505050505050565b62001c97620025f3565b62001ca28162002678565b50565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905262001d349084906200276f565b505050565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16331462001d97576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020546601000000000000900463ffffffff9081161462001ca2576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062001dfe838362002882565b90505b92915050565b601454760100000000000000000000000000000000000000000000900460ff161562001e5f576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60175483517c010000000000000000000000000000000000000000000000000000000090910463ffffffff16101562001ec4576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856040015163ffffffff16108062001f0a5750601654604086015163ffffffff780100000000000000000000000000000000000000000000000090920482169116115b1562001f42576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562001fad576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010085015173ffffffffffffffffffffffffffffffffffffffff9081166000908152602260205260409020546701000000000000009004166200201d576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846004600088815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160010160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050836005600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260076000888152602001908152602001600020908162002262919062003aba565b5060c085015161010086015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020526040902054620022ad916bffffffffffffffffffffffff16906200311c565b61010086015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020908152604080832093909355888252601d905220620022f2838262003aba565b506000868152601e602052604090206200230d828262003aba565b506200231b6002876200298d565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151562001dfe565b601554604080517f57e871e70000000000000000000000000000000000000000000000000000000081529051600092839273ffffffffffffffffffffffffffffffffffffffff90911691839183916385df51fd9160019184916357e871e79160048083019260209291908290030181865afa158015620023d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620023fe919062003a26565b6200240a919062003106565b6040518263ffffffff1660e01b81526004016200242991815260200190565b602060405180830381865afa15801562002447573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200246d919062003a26565b60165460408051602081019390935230908301527c0100000000000000000000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f8110156200258157838282815181106200253d576200253d620030a8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080620025788162003187565b9150506200251d565b5084600181111562002597576200259762003079565b60f81b81600f81518110620025b057620025b0620030a8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350620025ea8162003be1565b95945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462002676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620002b3565b565b3373ffffffffffffffffffffffffffffffffffffffff821603620026f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620002b3565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000620027d3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166200299b9092919063ffffffff16565b80519091501562001d345780806020019051810190620027f4919062003c24565b62001d34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401620002b3565b600081815260018301602052604081205480156200297b576000620028a960018362003106565b8554909150600090620028bf9060019062003106565b90508181146200292b576000866000018281548110620028e357620028e3620030a8565b9060005260206000200154905080876000018481548110620029095762002909620030a8565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200293f576200293f62003c44565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062001e01565b600091505062001e01565b5092915050565b600062001dfe8383620029b4565b6060620029ac848460008562002a06565b949350505050565b6000818152600183016020526040812054620029fd5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562001e01565b50600062001e01565b60608247101562002a9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401620002b3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405162002ac5919062003c73565b60006040518083038185875af1925050503d806000811462002b04576040519150601f19603f3d011682016040523d82523d6000602084013e62002b09565b606091505b509150915062002b1c8783838762002b27565b979650505050505050565b6060831562002bc257825160000362002bba5773ffffffffffffffffffffffffffffffffffffffff85163b62002bba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620002b3565b5081620029ac565b620029ac838381511562002bd95781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002b391906200355b565b50805462002c1d9062003132565b6000825580601f1062002c2e575050565b601f01602090049060005260206000209081019062001ca2919062002c5c565b6103ca8062003c9283390190565b5b8082111562002c73576000815560010162002c5d565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462001ca257600080fd5b803562002ca78162002c77565b919050565b60008060006040848603121562002cc257600080fd5b833567ffffffffffffffff8082111562002cdb57600080fd5b818601915086601f83011262002cf057600080fd5b81358181111562002d0057600080fd5b8760208260051b850101111562002d1657600080fd5b6020928301955093505084013562002d2e8162002c77565b809150509250925092565b60008083601f84011262002d4c57600080fd5b50813567ffffffffffffffff81111562002d6557600080fd5b60208301915083602082850101111562002d7e57600080fd5b9250929050565b6000806020838503121562002d9957600080fd5b823567ffffffffffffffff81111562002db157600080fd5b62002dbf8582860162002d39565b90969095509350505050565b803563ffffffff8116811462002ca757600080fd5b80356002811062002ca757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff8111828210171562002e465762002e4662002df0565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562002e965762002e9662002df0565b604052919050565b600067ffffffffffffffff82111562002ebb5762002ebb62002df0565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011262002ef957600080fd5b813562002f1062002f0a8262002e9e565b62002e4c565b81815284602083860101111562002f2657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060006101008a8c03121562002f6357600080fd5b62002f6e8a62002c9a565b985062002f7e60208b0162002dcb565b975062002f8e60408b0162002c9a565b965062002f9e60608b0162002de0565b955062002fae60808b0162002c9a565b945060a08a013567ffffffffffffffff8082111562002fcc57600080fd5b62002fda8d838e0162002d39565b909650945060c08c013591508082111562002ff457600080fd5b620030028d838e0162002ee7565b935060e08c01359150808211156200301957600080fd5b50620030288c828d0162002ee7565b9150509295985092959850929598565b6000602082840312156200304b57600080fd5b5035919050565b6000602082840312156200306557600080fd5b8135620030728162002c77565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111562001e015762001e01620030d7565b8082018082111562001e015762001e01620030d7565b600181811c908216806200314757607f821691505b60208210810362003181577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620031bb57620031bb620030d7565b5060010190565b600081518084526020808501945080840160005b838110156200329b5781518051151588528381015115158489015260408082015163ffffffff908116918a01919091526060808301518216908a015260808083015173ffffffffffffffffffffffffffffffffffffffff908116918b019190915260a0808401516fffffffffffffffffffffffffffffffff16908b015260c0808401516bffffffffffffffffffffffff16908b015260e080840151909216918a01919091526101009182015116908801526101209096019590820190600101620031d6565b509495945050505050565b600081518084526020808501945080840160005b838110156200329b57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101620032ba565b60005b838110156200330b578181015183820152602001620032f1565b50506000910152565b600081518084526200332e816020860160208601620032ee565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015620033ac5782840389526200339984835162003314565b988501989350908401906001016200337e565b5091979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a1115620033f657600080fd5b8960051b808c838601378301838103820160208501526200341a8282018b620031c2565b9150508281036040840152620034318189620032a6565b90508281036060840152620034478188620032a6565b905082810360808401526200345d818762003360565b905082810360a084015262003473818662003360565b905082810360c084015262003489818562003360565b9b9a5050505050505050505050565b600060208284031215620034ab57600080fd5b815160ff811681146200307257600080fd5b60ff8416815260ff83166020820152606060408201526000620025ea606083018462003314565b600060208284031215620034f757600080fd5b815167ffffffffffffffff8111156200350f57600080fd5b8201601f810184136200352157600080fd5b80516200353262002f0a8262002e9e565b8181528560208385010111156200354857600080fd5b620025ea826020830160208601620032ee565b60208152600062001dfe602083018462003314565b600067ffffffffffffffff8211156200358d576200358d62002df0565b5060051b60200190565b600082601f830112620035a957600080fd5b81356020620035bc62002f0a8362003570565b82815260059290921b84018101918181019086841115620035dc57600080fd5b8286015b84811015620035f95780358352918301918301620035e0565b509695505050505050565b801515811462001ca257600080fd5b803562002ca78162003604565b80356fffffffffffffffffffffffffffffffff8116811462002ca757600080fd5b80356bffffffffffffffffffffffff8116811462002ca757600080fd5b600082601f8301126200367057600080fd5b813560206200368362002f0a8362003570565b8281526101209283028501820192828201919087851115620036a457600080fd5b8387015b858110156200377e5781818a031215620036c25760008081fd5b620036cc62002e1f565b620036d78262003613565b8152620036e686830162003613565b868201526040620036f981840162002dcb565b9082015260606200370c83820162002dcb565b9082015260806200371f83820162002c9a565b9082015260a06200373283820162003620565b9082015260c06200374583820162003641565b9082015260e06200375883820162002dcb565b908201526101006200376c83820162002c9a565b908201528452928401928101620036a8565b5090979650505050505050565b600082601f8301126200379d57600080fd5b81356020620037b062002f0a8362003570565b82815260059290921b84018101918181019086841115620037d057600080fd5b8286015b84811015620035f9578035620037ea8162002c77565b8352918301918301620037d4565b600082601f8301126200380a57600080fd5b813560206200381d62002f0a8362003570565b82815260059290921b840181019181810190868411156200383d57600080fd5b8286015b84811015620035f957803567ffffffffffffffff811115620038635760008081fd5b620038738986838b010162002ee7565b84525091830191830162003841565b600080600080600080600060e0888a0312156200389e57600080fd5b873567ffffffffffffffff80821115620038b757600080fd5b620038c58b838c0162003597565b985060208a0135915080821115620038dc57600080fd5b620038ea8b838c016200365e565b975060408a01359150808211156200390157600080fd5b6200390f8b838c016200378b565b965060608a01359150808211156200392657600080fd5b620039348b838c016200378b565b955060808a01359150808211156200394b57600080fd5b620039598b838c01620037f8565b945060a08a01359150808211156200397057600080fd5b6200397e8b838c01620037f8565b935060c08a01359150808211156200399557600080fd5b50620039a48a828b01620037f8565b91505092959891949750929550565b600063ffffffff808316818103620039cf57620039cf620030d7565b6001019392505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60006020828403121562003a3957600080fd5b5051919050565b6bffffffffffffffffffffffff828116828216039080821115620029865762002986620030d7565b601f82111562001d3457600081815260208120601f850160051c8101602086101562003a915750805b601f850160051c820191505b8181101562003ab25782815560010162003a9d565b505050505050565b815167ffffffffffffffff81111562003ad75762003ad762002df0565b62003aef8162003ae8845462003132565b8462003a68565b602080601f83116001811462003b45576000841562003b0e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855562003ab2565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101562003b945788860151825594840194600190910190840162003b73565b508582101562003bd157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8051602080830151919081101562003181577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b60006020828403121562003c3757600080fd5b8151620030728162003604565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000825162003c87818460208701620032ee565b919091019291505056fe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a",
}
var AutomationRegistryLogicAABI = AutomationRegistryLogicAMetaData.ABI
@@ -5100,7 +5101,7 @@ func (AutomationRegistryLogicABillingConfigOverrideRemoved) Topic() common.Hash
}
func (AutomationRegistryLogicABillingConfigSet) Topic() common.Hash {
- return common.HexToHash("0x720a5849025dc4fd0061aed1bb30efd713cde64ce7f8d807953ecca27c8f143c")
+ return common.HexToHash("0xca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba3")
}
func (AutomationRegistryLogicACancelledUpkeepReport) Topic() common.Hash {
diff --git a/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go
index e68a1e0b75b..04087c52e11 100644
--- a/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go
+++ b/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go
@@ -34,6 +34,7 @@ type AutomationRegistryBase23BillingConfig struct {
GasFeePPB uint32
FlatFeeMilliCents *big.Int
PriceFeed common.Address
+ Decimals uint8
FallbackPrice *big.Int
MinSpend *big.Int
}
@@ -44,8 +45,8 @@ type AutomationRegistryBase23BillingOverrides struct {
}
var AutomationRegistryLogicBMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicC2_3\",\"name\":\"logicC\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"removeBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"billingOverrides\",\"type\":\"tuple\"}],\"name\":\"setBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20Fees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x6101806040523480156200001257600080fd5b50604051620055fd380380620055fd83398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051614ecd6200073060003960008181610177015261022401526000505060006127b10152600050506000612aa00152600061370e01526000612b7a015260008181610c2901528181610cea01528181610db501526128720152614ecd6000f3fe6080604052600436106101755760003560e01c80638765ecbe116100cb578063aed2e9291161007f578063ce7dc5b411610059578063ce7dc5b414610493578063f2fde38b146104b3578063f7d334ba146104d357610175565b8063aed2e9291461041c578063b148ab6b14610453578063cd7f71b51461047357610175565b80638dcf0fe7116100b05780638dcf0fe7146103bc578063a72aa27e146103dc578063a86e1781146103fc57610175565b80638765ecbe146103715780638da5cb5b1461039157610175565b806354b7faae1161012d57806371fae17f1161010757806371fae17f1461031c578063744bfe611461033c57806379ba50971461035c57610175565b806354b7faae146102a957806368d369d8146102c957806371791aa0146102e957610175565b8063349e8cca1161015e578063349e8cca146102155780634ee88d35146102695780635165f2f51461028957610175565b80631a2af011146101bc57806329c5efad146101dc575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156101b5573d6000f35b3d6000fd5b005b3480156101c857600080fd5b506101ba6101d7366004613ed7565b6104f3565b3480156101e857600080fd5b506101fc6101f736600461404b565b6105f9565b60405161020c949392919061416a565b60405180910390f35b34801561022157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161020c565b34801561027557600080fd5b506101ba6102843660046141ec565b6108d7565b34801561029557600080fd5b506101ba6102a4366004614238565b610939565b3480156102b557600080fd5b506101ba6102c4366004614251565b610aeb565b3480156102d557600080fd5b506101ba6102e436600461427d565b610d5e565b3480156102f557600080fd5b5061030961030436600461404b565b610fea565b60405161020c97969594939291906142be565b34801561032857600080fd5b506101ba610337366004614238565b61174e565b34801561034857600080fd5b506101ba610357366004613ed7565b6117e4565b34801561036857600080fd5b506101ba611c5c565b34801561037d57600080fd5b506101ba61038c366004614238565b611d59565b34801561039d57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610244565b3480156103c857600080fd5b506101ba6103d73660046141ec565b611f0e565b3480156103e857600080fd5b506101ba6103f736600461431e565b611f63565b34801561040857600080fd5b506101ba610417366004614343565b612062565b34801561042857600080fd5b5061043c6104373660046141ec565b612143565b60408051921515835260208301919091520161020c565b34801561045f57600080fd5b506101ba61046e366004614238565b6122ee565b34801561047f57600080fd5b506101ba61048e3660046141ec565b61251b565b34801561049f57600080fd5b506101fc6104ae3660046143bd565b6125d2565b3480156104bf57600080fd5b506101ba6104ce36600461449f565b612694565b3480156104df57600080fd5b506103096104ee366004614238565b6126a8565b6104fc826126e4565b3373ffffffffffffffffffffffffffffffffffffffff82160361054b576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116146105f55760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b60006060600080610608612799565b600086815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff620100008204811695830195909552660100000000000081048516606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490941660e0820152600290910154909216908201525a9150600080826080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561075e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078291906144cc565b73ffffffffffffffffffffffffffffffffffffffff16601660000160149054906101000a900463ffffffff1663ffffffff16896040516107c291906144e9565b60006040518083038160008787f1925050503d8060008114610800576040519150601f19603f3d011682016040523d82523d6000602084013e610805565b606091505b50915091505a6108159085614534565b93508161083e5760006040518060200160405280600081525060079650965096505050506108ce565b80806020019051810190610852919061459c565b90975095508661087e5760006040518060200160405280600081525060049650965096505050506108ce565b60185486517401000000000000000000000000000000000000000090910463ffffffff1610156108ca5760006040518060200160405280600081525060059650965096505050506108ce565b5050505b92959194509250565b6108e0836126e4565b6000838152601d602052604090206108f9828483614681565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664838360405161092c9291906147e5565b60405180910390a2505050565b610942816126e4565b600081815260046020908152604091829020825161012081018452815460ff808216151580845261010080840490921615159584019590955262010000820463ffffffff9081169684019690965266010000000000008204861660608401526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff908116608084015260018401546fffffffffffffffffffffffffffffffff811660a085015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08501527c0100000000000000000000000000000000000000000000000000000000900490951660e083015260029092015490931690830152610a7c576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610abb60028361280a565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b610af361281f565b73ffffffffffffffffffffffffffffffffffffffff8216610b40576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b4a612870565b90506000811215610b96576040517fcf47918100000000000000000000000000000000000000000000000000000000815260006004820152602481018390526044015b60405180910390fd5b80821115610bda576040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610b8d565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490526000917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015610c74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9891906147f9565b905080610cd1576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f5e110f8bc8a20b65dcc87f224bdf1cc039346e267118bae2739847f07321ffa885604051610d5091815260200190565b60405180910390a350505050565b610d6661281f565b73ffffffffffffffffffffffffffffffffffffffff8216610db3576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610e38576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e42612870565b1215610e7a576040517f981bb6a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015610ef6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1a9190614814565b610f249190614534565b905080821115610f6a576040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610b8d565b610f8b73ffffffffffffffffffffffffffffffffffffffff8516848461293f565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f5e110f8bc8a20b65dcc87f224bdf1cc039346e267118bae2739847f07321ffa884604051610d5091815260200190565b600060606000806000806000610ffe612799565b60006110098a6129d1565b905060006014604051806101200160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160139054906101000a900461ffff1661ffff1661ffff1681526020016000820160159054906101000a900460ff1660ff1660ff1681526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff161515151581526020016000820160189054906101000a900460ff161515151581526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d8152602001908152602001600020604051806101200160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900460ff161515151581526020016000820160029054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160069054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600a9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201601c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000808360a00151156113cc5750506040805160208101825260008082529290910151919a5098506009975089965063ffffffff169450859350839250611742915050565b606083015163ffffffff908116146114165750506040805160208101825260008082529290910151919a5098506001975089965063ffffffff169450859350839250611742915050565b8251156114555750506040805160208101825260008082529290910151919a5098506002975089965063ffffffff169450859350839250611742915050565b61145e84612a7c565b8094508198508299505050506114838e858786604001518b8b888a6101000151612c6e565b9050806bffffffffffffffffffffffff168360c001516bffffffffffffffffffffffff1610156114e55750506040805160208101825260008082529290910151919a5098506006975089965063ffffffff169450859350839250611742915050565b505060006114f48d858e612fde565b90505a9750600080836080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561154b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156f91906144cc565b73ffffffffffffffffffffffffffffffffffffffff16601660000160149054906101000a900463ffffffff1663ffffffff16846040516115af91906144e9565b60006040518083038160008787f1925050503d80600081146115ed576040519150601f19603f3d011682016040523d82523d6000602084013e6115f2565b606091505b50915091505a611602908b614534565b995081611688576018548151780100000000000000000000000000000000000000000000000090910463ffffffff1610156116675750506040805160208101825260008082529390910151929b509950600898505063ffffffff169450611742915050565b604090930151929a50600399505063ffffffff909116955061174292505050565b8080602001905181019061169c919061459c565b909d509b508c6116d65750506040805160208101825260008082529390910151929b509950600498505063ffffffff169450611742915050565b6018548c517401000000000000000000000000000000000000000090910463ffffffff1610156117305750506040805160208101825260008082529390910151929b509950600598505063ffffffff169450611742915050565b5050506040015163ffffffff16945050505b92959891949750929550565b6117566131be565b600081815260046020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055602390915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000001690555182917f97d0ef3f46a56168af653f547bdb6f77ec2b1d7d9bc6ba0193c2b340ec68064a91a250565b60145477010000000000000000000000000000000000000000000000900460ff161561183c576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff167701000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff81166118cb576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615158387015263ffffffff620100008304811684870152660100000000000083048116606085015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009093048316608085015260018501546fffffffffffffffffffffffffffffffff811660a08601526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08601527c010000000000000000000000000000000000000000000000000000000090041660e084015260029093015481169282019290925286855260059093529220549091163314611a0b576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601554604080517f57e871e7000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216916357e871e7916004808201926020929091908290030181865afa158015611a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9f9190614814565b816060015163ffffffff161115611ae2576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526004602090815260408083206001015461010085015173ffffffffffffffffffffffffffffffffffffffff1684526021909252909120547001000000000000000000000000000000009091046bffffffffffffffffffffffff1690611b4d908290614534565b6101008301805173ffffffffffffffffffffffffffffffffffffffff908116600090815260216020908152604080832095909555888252600490529290922060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff16905551611bd09116846bffffffffffffffffffffffff841661293f565b604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610b8d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611d62816126e4565b600081815260046020908152604091829020825161012081018452815460ff808216158015845261010080840490921615159584019590955262010000820463ffffffff9081169684019690965266010000000000008204861660608401526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff908116608084015260018401546fffffffffffffffffffffffffffffffff811660a085015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08501527c0100000000000000000000000000000000000000000000000000000000900490951660e083015260029092015490931690830152611e9c576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611ede60028361320f565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b611f17836126e4565b6000838152601e60205260409020611f30828483614681565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850838360405161092c9291906147e5565b6108fc8163ffffffff161080611fa0575060165463ffffffff78010000000000000000000000000000000000000000000000009091048116908216115b15611fd7576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611fe0826126e4565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166201000063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c91015b60405180910390a25050565b61206a6131be565b6000828152600460205260409020546601000000000000900463ffffffff908116146120c2576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055602390915290208190612110828261483e565b905050817fd8a6d79d170a55968079d3a89b960d86b4442aef6aac1d01e644c32b9e38b3408260405161205691906148c5565b60008061214e612799565b601454760100000000000000000000000000000000000000000000900460ff16156121a5576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615158386015262010000820463ffffffff90811684880181905266010000000000008404821660608601526a010000000000000000000090930473ffffffffffffffffffffffffffffffffffffffff9081166080860181905260018701546fffffffffffffffffffffffffffffffff811660a088015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08801527c0100000000000000000000000000000000000000000000000000000000900490921660e0860152600290950154909416908301528451601f890185900485028101850190955287855290936122e193899089908190840183828082843760009201919091525061321b92505050565b9097909650945050505050565b600081815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff6201000082048116958301959095526601000000000000810485166060830181905273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009092048216608084015260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c01000000000000000000000000000000000000000000000000000000009004861660e0840152600290930154169281019290925290911461242a576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612487576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b612524836126e4565b6017547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16811115612586576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260076020526040902061259f828483614681565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d838360405161092c9291906147e5565b600060606000806000634b56a42e60e01b8888886040516024016125f8939291906148fc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905061268189826105f9565b929c919b50995090975095505050505050565b61269c613436565b6126a5816134b7565b50565b6000606060008060008060006126cd8860405180602001604052806000815250610fea565b959e949d50929b5090995097509550909350915050565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612741576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020546601000000000000900463ffffffff908116146126a5576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612808576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061281683836135ac565b90505b92915050565b60185473ffffffffffffffffffffffffffffffffffffffff163314612808576040517fb6dfb7a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa15801561290c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129309190614814565b61293a9190614992565b905090565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526129cc9084906135fb565b505050565b6000818160045b600f811015612a5e577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612a1657612a166149b2565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612a4c57506000949350505050565b80612a56816149e1565b9150506129d8565b5081600f1a6001811115612a7457612a74614100565b949350505050565b600080600080846040015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612b09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2d9190614a33565b5094509092505050600081131580612b4457508142105b80612b655750828015612b655750612b5c8242614534565b8463ffffffff16105b15612b74576019549650612b78565b8096505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612be3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c079190614a33565b5094509092505050600081131580612c1e57508142105b80612c3f5750828015612c3f5750612c368242614534565b8463ffffffff16105b15612c4e57601a549550612c52565b8095505b8686612c5d8a613707565b965096509650505050509193909250565b6000808080896001811115612c8557612c85614100565b03612c94575062016b48612ce9565b6001896001811115612ca857612ca8614100565b03612cb757506201ccf0612ce9565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008a608001516001612cfc9190614a83565b612d0a9060ff166040614a9c565b601854612d38906103a49074010000000000000000000000000000000000000000900463ffffffff16614ab3565b612d429190614ab3565b601554604080517fde9ee35e0000000000000000000000000000000000000000000000000000000081528151939450600093849373ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa158015612db3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd79190614ac6565b90925090508183612de9836018614ab3565b612df39190614a9c565b60808f0151612e03906001614a83565b612e129060ff166115e0614a9c565b612e1c9190614ab3565b612e269190614ab3565b612e309085614ab3565b6101008e01516040517f125441400000000000000000000000000000000000000000000000000000000081526004810186905291955073ffffffffffffffffffffffffffffffffffffffff1690631254414090602401602060405180830381865afa158015612ea3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ec79190614814565b8d6060015161ffff16612eda9190614a9c565b94505050506000612eeb8b866137f8565b60008d815260046020526040902054909150610100900460ff1615612f505760008c81526023602090815260409182902082518084019093525463ffffffff811680845262ffffff640100000000909204821693830193845284529151909116908201525b6000612fba8c6040518061012001604052808d63ffffffff1681526020018681526020018781526020018c81526020018b81526020018a81526020018973ffffffffffffffffffffffffffffffffffffffff16815260200185815260200160001515815250613949565b60208101518151919250612fcd91614aea565b9d9c50505050505050505050505050565b60606000836001811115612ff457612ff4614100565b036130bd576000848152600760205260409081902090517f6e04ff0d000000000000000000000000000000000000000000000000000000009161303991602401614baa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506131b7565b60018360018111156130d1576130d1614100565b03612cb7576000828060200190518101906130ec9190614c23565b6000868152600760205260409081902090519192507f40691db40000000000000000000000000000000000000000000000000000000091613131918491602401614d33565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506131b79050565b9392505050565b60175473ffffffffffffffffffffffffffffffffffffffff163314612808576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006128168383613b19565b601454600090819077010000000000000000000000000000000000000000000000900460ff1615613278576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b00000000000000000000000000000000000000000000000000000000906132ed908590602401614dfe565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906133c09087908790600401614e11565b60408051808303816000875af11580156133de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134029190614e2a565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612808576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b8d565b3373ffffffffffffffffffffffffffffffffffffffff821603613536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b8d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120546135f357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612819565b506000612819565b600061365d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c0c9092919063ffffffff16565b8051909150156129cc578080602001905181019061367b91906147f9565b6129cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b8d565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379b9190614a33565b509350509250506000821315806137b157508042105b806137e157506000846040015162ffffff161180156137e157506137d58142614534565b846040015162ffffff16105b156137f1575050601b5492915050565b5092915050565b604080516060810182526000808252602080830182815283850183905273ffffffffffffffffffffffffffffffffffffffff868116845260229092528483208054640100000000810462ffffff1690925263ffffffff8216855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495909484936701000000000000009093049092169163feaf968c9160048082019260a0929091908290030181865afa1580156138ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138de9190614a33565b509350509250506000821315806138f457508042105b8061392457506000866040015162ffffff1611801561392457506139188142614534565b866040015162ffffff16105b156139385760018301546040850152613940565b604084018290525b50505092915050565b6040805160808101825260008082526020820181905291810182905260608101919091526000836060015161ffff1683606001516139879190614a9c565b9050826101000151801561399a5750803a105b156139a257503a5b60008360a001518460400151856020015186600001516139c29190614ab3565b6139cc9085614a9c565b6139d69190614ab3565b6139e09190614a9c565b90506139fe8460e0015160400151826139f99190614e56565b613c1b565b6bffffffffffffffffffffffff1683526080840151613a21906139f99083614e56565b6bffffffffffffffffffffffff16604084015260e084015160200151600090613a589062ffffff16683635c9adc5dea00000614a9c565b9050600081633b9aca008760a001518860e001516000015163ffffffff1689604001518a6000015189613a8b9190614a9c565b613a959190614ab3565b613a9f9190614a9c565b613aa99190614a9c565b613ab39190614e56565b613abd9190614ab3565b9050613ad68660e0015160400151826139f99190614e56565b6bffffffffffffffffffffffff1660208601526080860151613afc906139f99083614e56565b6bffffffffffffffffffffffff1660608601525050505092915050565b60008181526001830160205260408120548015613c02576000613b3d600183614534565b8554909150600090613b5190600190614534565b9050818114613bb6576000866000018281548110613b7157613b716149b2565b9060005260206000200154905080876000018481548110613b9457613b946149b2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613bc757613bc7614e91565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612819565b6000915050612819565b6060612a748484600085613cbd565b60006bffffffffffffffffffffffff821115613cb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610b8d565b5090565b606082471015613d4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b8d565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d7891906144e9565b60006040518083038185875af1925050503d8060008114613db5576040519150601f19603f3d011682016040523d82523d6000602084013e613dba565b606091505b5091509150613dcb87838387613dd6565b979650505050505050565b60608315613e6c578251600003613e655773ffffffffffffffffffffffffffffffffffffffff85163b613e65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b8d565b5081612a74565b612a748383815115613e815781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8d9190614dfe565b73ffffffffffffffffffffffffffffffffffffffff811681146126a557600080fd5b60008060408385031215613eea57600080fd5b823591506020830135613efc81613eb5565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613f5a57613f5a613f07565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613fa757613fa7613f07565b604052919050565b600067ffffffffffffffff821115613fc957613fc9613f07565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261400657600080fd5b813561401961401482613faf565b613f60565b81815284602083860101111561402e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561405e57600080fd5b82359150602083013567ffffffffffffffff81111561407c57600080fd5b61408885828601613ff5565b9150509250929050565b60005b838110156140ad578181015183820152602001614095565b50506000910152565b600081518084526140ce816020860160208601614092565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a8110614166577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b841515815260806020820152600061418560808301866140b6565b9050614194604083018561412f565b82606083015295945050505050565b60008083601f8401126141b557600080fd5b50813567ffffffffffffffff8111156141cd57600080fd5b6020830191508360208285010111156141e557600080fd5b9250929050565b60008060006040848603121561420157600080fd5b83359250602084013567ffffffffffffffff81111561421f57600080fd5b61422b868287016141a3565b9497909650939450505050565b60006020828403121561424a57600080fd5b5035919050565b6000806040838503121561426457600080fd5b823561426f81613eb5565b946020939093013593505050565b60008060006060848603121561429257600080fd5b833561429d81613eb5565b925060208401356142ad81613eb5565b929592945050506040919091013590565b871515815260e0602082015260006142d960e08301896140b6565b90506142e8604083018861412f565b8560608301528460808301528360a08301528260c083015298975050505050505050565b63ffffffff811681146126a557600080fd5b6000806040838503121561433157600080fd5b823591506020830135613efc8161430c565b600080828403606081121561435757600080fd5b8335925060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561438b57600080fd5b506020830190509250929050565b600067ffffffffffffffff8211156143b3576143b3613f07565b5060051b60200190565b600080600080606085870312156143d357600080fd5b8435935060208086013567ffffffffffffffff808211156143f357600080fd5b818801915088601f83011261440757600080fd5b813561441561401482614399565b81815260059190911b8301840190848101908b83111561443457600080fd5b8585015b8381101561446c578035858111156144505760008081fd5b61445e8e89838a0101613ff5565b845250918601918601614438565b5097505050604088013592508083111561448557600080fd5b5050614493878288016141a3565b95989497509550505050565b6000602082840312156144b157600080fd5b81356131b781613eb5565b80516144c781613eb5565b919050565b6000602082840312156144de57600080fd5b81516131b781613eb5565b600082516144fb818460208701614092565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561281957612819614505565b805180151581146144c757600080fd5b600082601f83011261456857600080fd5b815161457661401482613faf565b81815284602083860101111561458b57600080fd5b612a74826020830160208701614092565b600080604083850312156145af57600080fd5b6145b883614547565b9150602083015167ffffffffffffffff8111156145d457600080fd5b61408885828601614557565b600181811c908216806145f457607f821691505b60208210810361462d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156129cc57600081815260208120601f850160051c8101602086101561465a5750805b601f850160051c820191505b8181101561467957828155600101614666565b505050505050565b67ffffffffffffffff83111561469957614699613f07565b6146ad836146a783546145e0565b83614633565b6000601f8411600181146146ff57600085156146c95750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614795565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561474e578685013582556020948501946001909201910161472e565b5086821015614789577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000612a7460208301848661479c565b60006020828403121561480b57600080fd5b61281682614547565b60006020828403121561482657600080fd5b5051919050565b62ffffff811681146126a557600080fd5b81356148498161430c565b63ffffffff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000821617835560208401356148898161482d565b66ffffff000000008160201b16837fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000008416171784555050505050565b6040810182356148d48161430c565b63ffffffff16825260208301356148ea8161482d565b62ffffff811660208401525092915050565b6000604082016040835280865180835260608501915060608160051b8601019250602080890160005b83811015614971577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261495f8683516140b6565b95509382019390820190600101614925565b50508584038187015250505061498881858761479c565b9695505050505050565b81810360008312801583831316838312821617156137f1576137f1614505565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a1257614a12614505565b5060010190565b805169ffffffffffffffffffff811681146144c757600080fd5b600080600080600060a08688031215614a4b57600080fd5b614a5486614a19565b9450602086015193506040860151925060608601519150614a7760808701614a19565b90509295509295909350565b60ff818116838216019081111561281957612819614505565b808202811582820484141761281957612819614505565b8082018082111561281957612819614505565b60008060408385031215614ad957600080fd5b505080516020909101519092909150565b6bffffffffffffffffffffffff8181168382160190808211156137f1576137f1614505565b60008154614b1c816145e0565b808552602060018381168015614b395760018114614b7157614b9f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b8901019550614b9f565b866000528260002060005b85811015614b975781548a8201860152908301908401614b7c565b890184019650505b505050505092915050565b6020815260006128166020830184614b0f565b600082601f830112614bce57600080fd5b81516020614bde61401483614399565b82815260059290921b84018101918181019086841115614bfd57600080fd5b8286015b84811015614c185780518352918301918301614c01565b509695505050505050565b600060208284031215614c3557600080fd5b815167ffffffffffffffff80821115614c4d57600080fd5b908301906101008286031215614c6257600080fd5b614c6a613f36565b8251815260208301516020820152604083015160408201526060830151606082015260808301516080820152614ca260a084016144bc565b60a082015260c083015182811115614cb957600080fd5b614cc587828601614bbd565b60c08301525060e083015182811115614cdd57600080fd5b614ce987828601614557565b60e08301525095945050505050565b600081518084526020808501945080840160005b83811015614d2857815187529582019590820190600101614d0c565b509495945050505050565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c0840151610100808185015250614da4610140840182614cf8565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084830301610120850152614de082826140b6565b9150508281036020840152614df58185614b0f565b95945050505050565b60208152600061281660208301846140b6565b828152604060208201526000612a7460408301846140b6565b60008060408385031215614e3d57600080fd5b614e4683614547565b9150602083015190509250929050565b600082614e8c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicC2_3\",\"name\":\"logicC\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"removeBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"billingOverrides\",\"type\":\"tuple\"}],\"name\":\"setBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20Fees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x6101806040523480156200001257600080fd5b5060405162005c0e38038062005c0e83398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e051610100516101205161014051610160516154d46200073a60003960008181610182015261022f0152600081816120c5015261226b01526000612b910152600050506000612ec701526000613c3b01526000612fa1015260008181610c4701528181610d0801528181610dd30152612c5201526154d46000f3fe6080604052600436106101805760003560e01c80638765ecbe116100d6578063aed2e9291161007f578063ce7dc5b411610059578063ce7dc5b4146104b1578063f2fde38b146104d1578063f7d334ba146104f157610180565b8063aed2e9291461043a578063b148ab6b14610471578063cd7f71b51461049157610180565b8063948108f7116100b0578063948108f7146103e7578063a72aa27e146103fa578063a86e17811461041a57610180565b80638765ecbe1461037c5780638da5cb5b1461039c5780638dcf0fe7146103c757610180565b806354b7faae1161013857806371fae17f1161011257806371fae17f14610327578063744bfe611461034757806379ba50971461036757610180565b806354b7faae146102b457806368d369d8146102d457806371791aa0146102f457610180565b8063349e8cca11610169578063349e8cca146102205780634ee88d35146102745780635165f2f51461029457610180565b80631a2af011146101c757806329c5efad146101e7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156101c0573d6000f35b3d6000fd5b005b3480156101d357600080fd5b506101c56101e236600461437c565b610511565b3480156101f357600080fd5b506102076102023660046144f0565b610617565b604051610217949392919061460f565b60405180910390f35b34801561022c57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610217565b34801561028057600080fd5b506101c561028f366004614691565b6108f5565b3480156102a057600080fd5b506101c56102af3660046146dd565b610957565b3480156102c057600080fd5b506101c56102cf3660046146f6565b610b09565b3480156102e057600080fd5b506101c56102ef366004614722565b610d7c565b34801561030057600080fd5b5061031461030f3660046144f0565b611008565b6040516102179796959493929190614763565b34801561033357600080fd5b506101c56103423660046146dd565b61176c565b34801561035357600080fd5b506101c561036236600461437c565b611802565b34801561037357600080fd5b506101c5611c7a565b34801561038857600080fd5b506101c56103973660046146dd565b611d77565b3480156103a857600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661024f565b3480156103d357600080fd5b506101c56103e2366004614691565b611f2c565b6101c56103f53660046147b1565b611f81565b34801561040657600080fd5b506101c56104153660046147f9565b612343565b34801561042657600080fd5b506101c561043536600461481e565b612442565b34801561044657600080fd5b5061045a610455366004614691565b612523565b604080519215158352602083019190915201610217565b34801561047d57600080fd5b506101c561048c3660046146dd565b6126ce565b34801561049d57600080fd5b506101c56104ac366004614691565b6128fb565b3480156104bd57600080fd5b506102076104cc366004614898565b6129b2565b3480156104dd57600080fd5b506101c56104ec36600461497a565b612a74565b3480156104fd57600080fd5b5061031461050c3660046146dd565b612a88565b61051a82612ac4565b3373ffffffffffffffffffffffffffffffffffffffff821603610569576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116146106135760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b60006060600080610626612b79565b600086815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff620100008204811695830195909552660100000000000081048516606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490941660e0820152600290910154909216908201525a9150600080826080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561077c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a091906149a7565b73ffffffffffffffffffffffffffffffffffffffff16601660000160149054906101000a900463ffffffff1663ffffffff16896040516107e091906149c4565b60006040518083038160008787f1925050503d806000811461081e576040519150601f19603f3d011682016040523d82523d6000602084013e610823565b606091505b50915091505a6108339085614a0f565b93508161085c5760006040518060200160405280600081525060079650965096505050506108ec565b808060200190518101906108709190614a77565b90975095508661089c5760006040518060200160405280600081525060049650965096505050506108ec565b60185486517401000000000000000000000000000000000000000090910463ffffffff1610156108e85760006040518060200160405280600081525060059650965096505050506108ec565b5050505b92959194509250565b6108fe83612ac4565b6000838152601d60205260409020610917828483614b5c565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664838360405161094a929190614cc0565b60405180910390a2505050565b61096081612ac4565b600081815260046020908152604091829020825161012081018452815460ff808216151580845261010080840490921615159584019590955262010000820463ffffffff9081169684019690965266010000000000008204861660608401526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff908116608084015260018401546fffffffffffffffffffffffffffffffff811660a085015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08501527c0100000000000000000000000000000000000000000000000000000000900490951660e083015260029092015490931690830152610a9a576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ad9600283612bea565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b610b11612bff565b73ffffffffffffffffffffffffffffffffffffffff8216610b5e576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b68612c50565b90506000811215610bb4576040517fcf47918100000000000000000000000000000000000000000000000000000000815260006004820152602481018390526044015b60405180910390fd5b80821115610bf8576040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610bab565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490526000917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015610c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb69190614cd4565b905080610cef576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f5e110f8bc8a20b65dcc87f224bdf1cc039346e267118bae2739847f07321ffa885604051610d6e91815260200190565b60405180910390a350505050565b610d84612bff565b73ffffffffffffffffffffffffffffffffffffffff8216610dd1576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610e56576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e60612c50565b1215610e98576040517f981bb6a000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015610f14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f389190614cef565b610f429190614a0f565b905080821115610f88576040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610bab565b610fa973ffffffffffffffffffffffffffffffffffffffff85168484612d1f565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f5e110f8bc8a20b65dcc87f224bdf1cc039346e267118bae2739847f07321ffa884604051610d6e91815260200190565b60006060600080600080600061101c612b79565b60006110278a612df8565b905060006014604051806101200160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160139054906101000a900461ffff1661ffff1661ffff1681526020016000820160159054906101000a900460ff1660ff1660ff1681526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff161515151581526020016000820160189054906101000a900460ff161515151581526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d8152602001908152602001600020604051806101200160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900460ff161515151581526020016000820160029054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160069054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600a9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201601c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000808360a00151156113ea5750506040805160208101825260008082529290910151919a5098506009975089965063ffffffff169450859350839250611760915050565b606083015163ffffffff908116146114345750506040805160208101825260008082529290910151919a5098506001975089965063ffffffff169450859350839250611760915050565b8251156114735750506040805160208101825260008082529290910151919a5098506002975089965063ffffffff169450859350839250611760915050565b61147c84612ea3565b8094508198508299505050506114a18e858786604001518b8b888a6101000151613095565b9050806bffffffffffffffffffffffff168360c001516bffffffffffffffffffffffff1610156115035750506040805160208101825260008082529290910151919a5098506006975089965063ffffffff169450859350839250611760915050565b505060006115128d858e613405565b90505a9750600080836080015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611569573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158d91906149a7565b73ffffffffffffffffffffffffffffffffffffffff16601660000160149054906101000a900463ffffffff1663ffffffff16846040516115cd91906149c4565b60006040518083038160008787f1925050503d806000811461160b576040519150601f19603f3d011682016040523d82523d6000602084013e611610565b606091505b50915091505a611620908b614a0f565b9950816116a6576018548151780100000000000000000000000000000000000000000000000090910463ffffffff1610156116855750506040805160208101825260008082529390910151929b509950600898505063ffffffff169450611760915050565b604090930151929a50600399505063ffffffff909116955061176092505050565b808060200190518101906116ba9190614a77565b909d509b508c6116f45750506040805160208101825260008082529390910151929b509950600498505063ffffffff169450611760915050565b6018548c517401000000000000000000000000000000000000000090910463ffffffff16101561174e5750506040805160208101825260008082529390910151929b509950600598505063ffffffff169450611760915050565b5050506040015163ffffffff16945050505b92959891949750929550565b6117746135e5565b600081815260046020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055602390915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000001690555182917f97d0ef3f46a56168af653f547bdb6f77ec2b1d7d9bc6ba0193c2b340ec68064a91a250565b60145477010000000000000000000000000000000000000000000000900460ff161561185a576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff167701000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff81166118e9576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615158387015263ffffffff620100008304811684870152660100000000000083048116606085015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009093048316608085015260018501546fffffffffffffffffffffffffffffffff811660a08601526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08601527c010000000000000000000000000000000000000000000000000000000090041660e084015260029093015481169282019290925286855260059093529220549091163314611a29576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601554604080517f57e871e7000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff909216916357e871e7916004808201926020929091908290030181865afa158015611a99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611abd9190614cef565b816060015163ffffffff161115611b00576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526004602090815260408083206001015461010085015173ffffffffffffffffffffffffffffffffffffffff1684526021909252909120547001000000000000000000000000000000009091046bffffffffffffffffffffffff1690611b6b908290614a0f565b6101008301805173ffffffffffffffffffffffffffffffffffffffff908116600090815260216020908152604080832095909555888252600490529290922060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff16905551611bee9116846bffffffffffffffffffffffff8416612d1f565b604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611cfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610bab565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611d8081612ac4565b600081815260046020908152604091829020825161012081018452815460ff808216158015845261010080840490921615159584019590955262010000820463ffffffff9081169684019690965266010000000000008204861660608401526a010000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff908116608084015260018401546fffffffffffffffffffffffffffffffff811660a085015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08501527c0100000000000000000000000000000000000000000000000000000000900490951660e083015260029092015490931690830152611eba576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611efc600283613636565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b611f3583612ac4565b6000838152601e60205260409020611f4e828483614b5c565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850838360405161094a929190614cc0565b600082815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff6201000082048116958301959095526601000000000000810485166060830181905273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009092048216608084015260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c01000000000000000000000000000000000000000000000000000000009004861660e084015260029093015416928101929092529091146120bd576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3415612159577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681610100015173ffffffffffffffffffffffffffffffffffffffff161461214d576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61215634613642565b91505b818160c001516121699190614d08565b600084815260046020908152604080832060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000006bffffffffffffffffffffffff9687160217905561010085015173ffffffffffffffffffffffffffffffffffffffff16835260219091529020546121f991841690614d2d565b61010082015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020526040812091909155349003612269576101008101516122649073ffffffffffffffffffffffffffffffffffffffff1633306bffffffffffffffffffffffff86166136e4565b6122f9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836bffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016000604051808303818588803b1580156122df57600080fd5b505af11580156122f3573d6000803e3d6000fd5b50505050505b6040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6108fc8163ffffffff161080612380575060165463ffffffff78010000000000000000000000000000000000000000000000009091048116908216115b156123b7576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123c082612ac4565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ffff166201000063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c91015b60405180910390a25050565b61244a6135e5565b6000828152600460205260409020546601000000000000900463ffffffff908116146124a2576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790556023909152902081906124f08282614d51565b905050817fd8a6d79d170a55968079d3a89b960d86b4442aef6aac1d01e644c32b9e38b340826040516124369190614dd8565b60008061252e612b79565b601454760100000000000000000000000000000000000000000000900460ff1615612585576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615158386015262010000820463ffffffff90811684880181905266010000000000008404821660608601526a010000000000000000000090930473ffffffffffffffffffffffffffffffffffffffff9081166080860181905260018701546fffffffffffffffffffffffffffffffff811660a088015270010000000000000000000000000000000081046bffffffffffffffffffffffff1660c08801527c0100000000000000000000000000000000000000000000000000000000900490921660e0860152600290950154909416908301528451601f890185900485028101850190955287855290936126c193899089908190840183828082843760009201919091525061374892505050565b9097909650945050505050565b600081815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff6201000082048116958301959095526601000000000000810485166060830181905273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009092048216608084015260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c01000000000000000000000000000000000000000000000000000000009004861660e0840152600290930154169281019290925290911461280a576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612867576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b61290483612ac4565b6017547c0100000000000000000000000000000000000000000000000000000000900463ffffffff16811115612966576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260076020526040902061297f828483614b5c565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d838360405161094a929190614cc0565b600060606000806000634b56a42e60e01b8888886040516024016129d893929190614e0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050612a618982610617565b929c919b50995090975095505050505050565b612a7c613963565b612a85816139e4565b50565b600060606000806000806000612aad8860405180602001604052806000815250611008565b959e949d50929b5090995097509550909350915050565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612b21576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020546601000000000000900463ffffffff90811614612a85576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612be8576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612bf68383613ad9565b90505b92915050565b60185473ffffffffffffffffffffffffffffffffffffffff163314612be8576040517fb6dfb7a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166000818152602160205260408082205490517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152919290916370a0823190602401602060405180830381865afa158015612cec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d109190614cef565b612d1a9190614ea5565b905090565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052612df39084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613b28565b505050565b6000818160045b600f811015612e85577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612e3d57612e3d614ec5565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612e7357506000949350505050565b80612e7d81614ef4565b915050612dff565b5081600f1a6001811115612e9b57612e9b6145a5565b949350505050565b600080600080846040015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f549190614f46565b5094509092505050600081131580612f6b57508142105b80612f8c5750828015612f8c5750612f838242614a0f565b8463ffffffff16105b15612f9b576019549650612f9f565b8096505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561300a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302e9190614f46565b509450909250505060008113158061304557508142105b806130665750828015613066575061305d8242614a0f565b8463ffffffff16105b1561307557601a549550613079565b8095505b86866130848a613c34565b965096509650505050509193909250565b60008080808960018111156130ac576130ac6145a5565b036130bb575062016b48613110565b60018960018111156130cf576130cf6145a5565b036130de57506201ccf0613110565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008a6080015160016131239190614f96565b6131319060ff166040614faf565b60185461315f906103a49074010000000000000000000000000000000000000000900463ffffffff16614d2d565b6131699190614d2d565b601554604080517fde9ee35e0000000000000000000000000000000000000000000000000000000081528151939450600093849373ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa1580156131da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131fe9190614fc6565b90925090508183613210836018614d2d565b61321a9190614faf565b60808f015161322a906001614f96565b6132399060ff166115e0614faf565b6132439190614d2d565b61324d9190614d2d565b6132579085614d2d565b6101008e01516040517f125441400000000000000000000000000000000000000000000000000000000081526004810186905291955073ffffffffffffffffffffffffffffffffffffffff1690631254414090602401602060405180830381865afa1580156132ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ee9190614cef565b8d6060015161ffff166133019190614faf565b945050505060006133128b86613d25565b60008d815260046020526040902054909150610100900460ff16156133775760008c81526023602090815260409182902082518084018452905463ffffffff811680835264010000000090910462ffffff908116928401928352928501525116908201525b60006133e18c6040518061012001604052808d63ffffffff1681526020018681526020018781526020018c81526020018b81526020018a81526020018973ffffffffffffffffffffffffffffffffffffffff16815260200185815260200160001515815250613ea1565b602081015181519192506133f491614d08565b9d9c50505050505050505050505050565b6060600083600181111561341b5761341b6145a5565b036134e4576000848152600760205260409081902090517f6e04ff0d000000000000000000000000000000000000000000000000000000009161346091602401615085565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506135de565b60018360018111156134f8576134f86145a5565b036130de5760008280602001905181019061351391906150fe565b6000868152600760205260409081902090519192507f40691db4000000000000000000000000000000000000000000000000000000009161355891849160240161520e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506135de9050565b9392505050565b60175473ffffffffffffffffffffffffffffffffffffffff163314612be8576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612bf683836140f6565b60006bffffffffffffffffffffffff8211156136e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610bab565b5090565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526137429085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612d71565b50505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff16156137a5576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061381a9085906024016152d9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906138ed90879087906004016152ec565b60408051808303816000875af115801561390b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061392f9190615305565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612be8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610bab565b3373ffffffffffffffffffffffffffffffffffffffff821603613a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610bab565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054613b2057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612bf9565b506000612bf9565b6000613b8a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166141e99092919063ffffffff16565b805190915015612df35780806020019051810190613ba89190614cd4565b612df3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610bab565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cc89190614f46565b50935050925050600082131580613cde57508042105b80613d0e57506000846040015162ffffff16118015613d0e5750613d028142614a0f565b846040015162ffffff16105b15613d1e575050601b5492915050565b5092915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015613e12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e369190614f46565b50935050925050600082131580613e4c57508042105b80613e7c57506000866040015162ffffff16118015613e7c5750613e708142614a0f565b866040015162ffffff16105b15613e905760018301546060850152613e98565b606084018290525b50505092915050565b60408051608081018252600080825260208201819052918101829052606081019190915260008260e001516000015160ff1690506000846060015161ffff168460600151613eef9190614faf565b90508361010001518015613f025750803a105b15613f0a57503a5b600060128311613f1b576001613f31565b613f26601284614a0f565b613f3190600a615451565b9050600060128410613f44576001613f5a565b613f4f846012614a0f565b613f5a90600a615451565b905060008660a00151876040015188602001518960000151613f7c9190614d2d565b613f869087614faf565b613f909190614d2d565b613f9a9190614faf565b9050613fcc828860e0015160600151613fb39190614faf565b613fbd8584614faf565b613fc7919061545d565b613642565b6bffffffffffffffffffffffff1686526080870151613fef90613fc7908361545d565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906140289062ffffff16683635c9adc5dea00000614faf565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b61405b9190614faf565b6140659190614d2d565b61406f9190614faf565b6140799190614faf565b614083919061545d565b61408d9190614d2d565b90506140b0848a60e00151606001516140a69190614faf565b613fbd8784614faf565b6bffffffffffffffffffffffff16602089015260808901516140d690613fc7908361545d565b6bffffffffffffffffffffffff1660608901525050505050505092915050565b600081815260018301602052604081205480156141df57600061411a600183614a0f565b855490915060009061412e90600190614a0f565b905081811461419357600086600001828154811061414e5761414e614ec5565b906000526020600020015490508087600001848154811061417157614171614ec5565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141a4576141a4615498565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612bf9565b6000915050612bf9565b6060612e9b8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161421d91906149c4565b60006040518083038185875af1925050503d806000811461425a576040519150601f19603f3d011682016040523d82523d6000602084013e61425f565b606091505b50915091506142708783838761427b565b979650505050505050565b6060831561431157825160000361430a5773ffffffffffffffffffffffffffffffffffffffff85163b61430a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610bab565b5081612e9b565b612e9b83838151156143265781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab91906152d9565b73ffffffffffffffffffffffffffffffffffffffff81168114612a8557600080fd5b6000806040838503121561438f57600080fd5b8235915060208301356143a18161435a565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156143ff576143ff6143ac565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561444c5761444c6143ac565b604052919050565b600067ffffffffffffffff82111561446e5761446e6143ac565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126144ab57600080fd5b81356144be6144b982614454565b614405565b8181528460208386010111156144d357600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561450357600080fd5b82359150602083013567ffffffffffffffff81111561452157600080fd5b61452d8582860161449a565b9150509250929050565b60005b8381101561455257818101518382015260200161453a565b50506000910152565b60008151808452614573816020860160208601614537565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a811061460b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b841515815260806020820152600061462a608083018661455b565b905061463960408301856145d4565b82606083015295945050505050565b60008083601f84011261465a57600080fd5b50813567ffffffffffffffff81111561467257600080fd5b60208301915083602082850101111561468a57600080fd5b9250929050565b6000806000604084860312156146a657600080fd5b83359250602084013567ffffffffffffffff8111156146c457600080fd5b6146d086828701614648565b9497909650939450505050565b6000602082840312156146ef57600080fd5b5035919050565b6000806040838503121561470957600080fd5b82356147148161435a565b946020939093013593505050565b60008060006060848603121561473757600080fd5b83356147428161435a565b925060208401356147528161435a565b929592945050506040919091013590565b871515815260e06020820152600061477e60e083018961455b565b905061478d60408301886145d4565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080604083850312156147c457600080fd5b8235915060208301356bffffffffffffffffffffffff811681146143a157600080fd5b63ffffffff81168114612a8557600080fd5b6000806040838503121561480c57600080fd5b8235915060208301356143a1816147e7565b600080828403606081121561483257600080fd5b8335925060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561486657600080fd5b506020830190509250929050565b600067ffffffffffffffff82111561488e5761488e6143ac565b5060051b60200190565b600080600080606085870312156148ae57600080fd5b8435935060208086013567ffffffffffffffff808211156148ce57600080fd5b818801915088601f8301126148e257600080fd5b81356148f06144b982614874565b81815260059190911b8301840190848101908b83111561490f57600080fd5b8585015b838110156149475780358581111561492b5760008081fd5b6149398e89838a010161449a565b845250918601918601614913565b5097505050604088013592508083111561496057600080fd5b505061496e87828801614648565b95989497509550505050565b60006020828403121561498c57600080fd5b81356135de8161435a565b80516149a28161435a565b919050565b6000602082840312156149b957600080fd5b81516135de8161435a565b600082516149d6818460208701614537565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115612bf957612bf96149e0565b805180151581146149a257600080fd5b600082601f830112614a4357600080fd5b8151614a516144b982614454565b818152846020838601011115614a6657600080fd5b612e9b826020830160208701614537565b60008060408385031215614a8a57600080fd5b614a9383614a22565b9150602083015167ffffffffffffffff811115614aaf57600080fd5b61452d85828601614a32565b600181811c90821680614acf57607f821691505b602082108103614b08577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115612df357600081815260208120601f850160051c81016020861015614b355750805b601f850160051c820191505b81811015614b5457828155600101614b41565b505050505050565b67ffffffffffffffff831115614b7457614b746143ac565b614b8883614b828354614abb565b83614b0e565b6000601f841160018114614bda5760008515614ba45750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614c70565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015614c295786850135825560209485019460019092019101614c09565b5086821015614c64577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000612e9b602083018486614c77565b600060208284031215614ce657600080fd5b612bf682614a22565b600060208284031215614d0157600080fd5b5051919050565b6bffffffffffffffffffffffff818116838216019080821115613d1e57613d1e6149e0565b80820180821115612bf957612bf96149e0565b62ffffff81168114612a8557600080fd5b8135614d5c816147e7565b63ffffffff811690508154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000082161783556020840135614d9c81614d40565b66ffffff000000008160201b16837fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000008416171784555050505050565b604081018235614de7816147e7565b63ffffffff1682526020830135614dfd81614d40565b62ffffff811660208401525092915050565b6000604082016040835280865180835260608501915060608160051b8601019250602080890160005b83811015614e84577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552614e7286835161455b565b95509382019390820190600101614e38565b505085840381870152505050614e9b818587614c77565b9695505050505050565b8181036000831280158383131683831282161715613d1e57613d1e6149e0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614f2557614f256149e0565b5060010190565b805169ffffffffffffffffffff811681146149a257600080fd5b600080600080600060a08688031215614f5e57600080fd5b614f6786614f2c565b9450602086015193506040860151925060608601519150614f8a60808701614f2c565b90509295509295909350565b60ff8181168382160190811115612bf957612bf96149e0565b8082028115828204841417612bf957612bf96149e0565b60008060408385031215614fd957600080fd5b505080516020909101519092909150565b60008154614ff781614abb565b808552602060018381168015615014576001811461504c5761507a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955061507a565b866000528260002060005b858110156150725781548a8201860152908301908401615057565b890184019650505b505050505092915050565b602081526000612bf66020830184614fea565b600082601f8301126150a957600080fd5b815160206150b96144b983614874565b82815260059290921b840181019181810190868411156150d857600080fd5b8286015b848110156150f357805183529183019183016150dc565b509695505050505050565b60006020828403121561511057600080fd5b815167ffffffffffffffff8082111561512857600080fd5b90830190610100828603121561513d57600080fd5b6151456143db565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015261517d60a08401614997565b60a082015260c08301518281111561519457600080fd5b6151a087828601615098565b60c08301525060e0830151828111156151b857600080fd5b6151c487828601614a32565b60e08301525095945050505050565b600081518084526020808501945080840160005b83811015615203578151875295820195908201906001016151e7565b509495945050505050565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c084015161010080818501525061527f6101408401826151d3565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0848303016101208501526152bb828261455b565b91505082810360208401526152d08185614fea565b95945050505050565b602081526000612bf6602083018461455b565b828152604060208201526000612e9b604083018461455b565b6000806040838503121561531857600080fd5b61532183614a22565b9150602083015190509250929050565b600181815b8085111561538a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615370576153706149e0565b8085161561537d57918102915b93841c9390800290615336565b509250929050565b6000826153a157506001612bf9565b816153ae57506000612bf9565b81600181146153c457600281146153ce576153ea565b6001915050612bf9565b60ff8411156153df576153df6149e0565b50506001821b612bf9565b5060208310610133831016604e8410600b841016171561540d575081810a612bf9565b6154178383615331565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615449576154496149e0565b029392505050565b6000612bf68383615392565b600082615493577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a",
}
var AutomationRegistryLogicBABI = AutomationRegistryLogicBMetaData.ABI
@@ -252,6 +253,18 @@ func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) Acce
return _AutomationRegistryLogicB.Contract.AcceptUpkeepAdmin(&_AutomationRegistryLogicB.TransactOpts, id)
}
+func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) AddFunds(opts *bind.TransactOpts, id *big.Int, amount *big.Int) (*types.Transaction, error) {
+ return _AutomationRegistryLogicB.contract.Transact(opts, "addFunds", id, amount)
+}
+
+func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) AddFunds(id *big.Int, amount *big.Int) (*types.Transaction, error) {
+ return _AutomationRegistryLogicB.Contract.AddFunds(&_AutomationRegistryLogicB.TransactOpts, id, amount)
+}
+
+func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) AddFunds(id *big.Int, amount *big.Int) (*types.Transaction, error) {
+ return _AutomationRegistryLogicB.Contract.AddFunds(&_AutomationRegistryLogicB.TransactOpts, id, amount)
+}
+
func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) CheckCallback(opts *bind.TransactOpts, id *big.Int, values [][]byte, extraData []byte) (*types.Transaction, error) {
return _AutomationRegistryLogicB.contract.Transact(opts, "checkCallback", id, values, extraData)
}
@@ -5268,7 +5281,7 @@ func (AutomationRegistryLogicBBillingConfigOverrideRemoved) Topic() common.Hash
}
func (AutomationRegistryLogicBBillingConfigSet) Topic() common.Hash {
- return common.HexToHash("0x720a5849025dc4fd0061aed1bb30efd713cde64ce7f8d807953ecca27c8f143c")
+ return common.HexToHash("0xca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba3")
}
func (AutomationRegistryLogicBCancelledUpkeepReport) Topic() common.Hash {
@@ -5412,6 +5425,8 @@ type AutomationRegistryLogicBInterface interface {
AcceptUpkeepAdmin(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error)
+ AddFunds(opts *bind.TransactOpts, id *big.Int, amount *big.Int) (*types.Transaction, error)
+
CheckCallback(opts *bind.TransactOpts, id *big.Int, values [][]byte, extraData []byte) (*types.Transaction, error)
CheckUpkeep(opts *bind.TransactOpts, id *big.Int, triggerData []byte) (*types.Transaction, error)
diff --git a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go
index 71ef298db95..d648604895b 100644
--- a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go
+++ b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go
@@ -34,6 +34,7 @@ type AutomationRegistryBase23BillingConfig struct {
GasFeePPB uint32
FlatFeeMilliCents *big.Int
PriceFeed common.Address
+ Decimals uint8
FallbackPrice *big.Int
MinSpend *big.Int
}
@@ -63,8 +64,8 @@ type AutomationRegistryBase23OnchainConfig struct {
}
var AutomationRegistryMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicA2_3\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x6101806040523480156200001257600080fd5b50604051620066dd380380620066dd83398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051615f9f6200073e6000396000818160c9015261017c015260008181610efb015261115701526000505060005050600050506000613d04015260005050600081816112470152818161135501528181611480015281816114ca01528181611a18015261342f0152615f9f6000f3fe6080604052600436106100c75760003560e01c8063948108f711610074578063b1dc65a41161004e578063b1dc65a414610314578063e3d0e71214610334578063f2fde38b14610354576100c7565b8063948108f71461029b578063a4c0ed36146102ae578063afcb95d7146102ce576100c7565b80637bee169d116100a55780637bee169d146101d657806381ff7048146101f65780638da5cb5b14610270576100c7565b8063181f5a771461010e578063349e8cca1461016d57806379ba5097146101c1575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610107573d6000f35b3d6000fd5b005b34801561011a57600080fd5b506101576040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b60405161016491906149a9565b60405180910390f35b34801561017957600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b3480156101cd57600080fd5b5061010c610374565b3480156101e257600080fd5b5061010c6101f1366004614f1e565b610476565b34801561020257600080fd5b5061024d60175460135463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b34801561027c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661019c565b61010c6102a9366004615036565b610db7565b3480156102ba57600080fd5b5061010c6102c93660046150af565b61122f565b3480156102da57600080fd5b50601354601454604080516000815260208101939093526c0100000000000000000000000090910463ffffffff1690820152606001610164565b34801561032057600080fd5b5061010c61032f366004615150565b61154b565b34801561034057600080fd5b5061010c61034f366004615207565b61182c565b34801561036057600080fd5b5061010c61036f3660046152d4565b611866565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61047e61187a565b601f885111156104ba576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560ff166000036104f7576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86518851141580610516575061050e866003615327565b60ff16885111155b1561054d576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051825114610588576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61059282826118fd565b61059c8888611d65565b604051806101200160405280601460000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001600063ffffffff1681526020018660a0015162ffffff16815260200186610120015161ffff1681526020018760ff168152602001601460000160169054906101000a900460ff1615158152602001601460000160179054906101000a900460ff1615158152602001866080015115158152602001866101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548162ffffff021916908362ffffff16021790555060608201518160000160136101000a81548161ffff021916908361ffff16021790555060808201518160000160156101000a81548160ff021916908360ff16021790555060a08201518160000160166101000a81548160ff02191690831515021790555060c08201518160000160176101000a81548160ff02191690831515021790555060e08201518160000160186101000a81548160ff0219169083151502179055506101008201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050604051806101600160405280866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866000015163ffffffff168152602001866020015163ffffffff1681526020016016600001601c9054906101000a900463ffffffff1663ffffffff16815260200186610100015173ffffffffffffffffffffffffffffffffffffffff168152602001601660010160149054906101000a900463ffffffff1663ffffffff168152602001601660010160189054906101000a900463ffffffff1663ffffffff168152602001866040015163ffffffff16815260200186610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018660c0015163ffffffff1681526020018660e0015163ffffffff16815250601660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160186101000a81548163ffffffff021916908363ffffffff160217905550905050846101600151601981905550846101800151601a81905550846101a00151601b819055506000601660010160189054906101000a900463ffffffff169050856101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ba2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc69190615343565b601780547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601491610c3d9185917401000000000000000000000000000000000000000090041661535c565b92506101000a81548163ffffffff021916908363ffffffff160217905550600086604051602001610c6e91906153ca565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601754909150610cd3904690309074010000000000000000000000000000000000000000900463ffffffff168d8d8d878d8d612426565b601355600960008181610ce68282614890565b5050505060005b876101c0015151811015610d4057610d2d886101c001518281518110610d1557610d15615550565b602002602001015160096124d090919063ffffffff16565b5080610d388161557f565b915050610ced565b506013546017546040517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0592610da39286927401000000000000000000000000000000000000000090910463ffffffff16908f908f908f9089908f908f906155b7565b60405180910390a150505050505050505050565b600082815260046020908152604091829020825161012081018452815460ff8082161515835261010080830490911615159483019490945263ffffffff6201000082048116958301959095526601000000000000810485166060830181905273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009092048216608084015260018401546fffffffffffffffffffffffffffffffff811660a08501526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08501527c01000000000000000000000000000000000000000000000000000000009004861660e08401526002909301541692810192909252909114610ef3576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3415610f8f577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681610100015173ffffffffffffffffffffffffffffffffffffffff1614610f83576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8c346124fb565b91505b818160c00151610f9f919061564d565b600084815260046020908152604080832060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000006bffffffffffffffffffffffff9687160217905561010085015173ffffffffffffffffffffffffffffffffffffffff168352602190915290205461102f91841690615672565b61010082015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020526040812091909155349003611155576101008101516040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff8416604482015260009173ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156110f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111169190615690565b90508061114f576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506111e5565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836bffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016000604051808303818588803b1580156111cb57600080fd5b505af11580156111df573d6000803e3d6000fd5b50505050505b6040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461129e576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146112d8576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006112e6828401846156ad565b6000818152600460205260409020549091506601000000000000900463ffffffff90811614611341576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600201547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146113c5576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090206001015461140490859070010000000000000000000000000000000090046bffffffffffffffffffffffff1661564d565b600082815260046020908152604080832060010180546bffffffffffffffffffffffff95909516700100000000000000000000000000000000027fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff9095169490941790935573ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001682526021905220546114b3908590615672565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660009081526021602090815260409182902093909355516bffffffffffffffffffffffff871681529087169183917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203910160405180910390a35050505050565b60005a60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff75010000000000000000000000000000000000000000008304811660808301527601000000000000000000000000000000000000000000008304811615801560a08401527701000000000000000000000000000000000000000000000084048216151560c0840152780100000000000000000000000000000000000000000000000090930416151560e082015260155473ffffffffffffffffffffffffffffffffffffffff166101008201529192506116af576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff166116f8576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013548a3514611734576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60808101516117449060016156c6565b60ff16861415806117555750858414155b1561178c576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61179c8a8a8a8a8a8a8a8a61259d565b60006117a88a8a612806565b905060208b0135600881901c63ffffffff166117c58484876128bf565b836020015163ffffffff168163ffffffff16111561181d57601480547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b600080600085806020019051810190611845919061582e565b92509250925061185b8989898689898888610476565b505050505050505050565b61186e61187a565b611877816134a5565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146118fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103f1565b565b60005b6024548110156119bb57602260006024838154811061192157611921615550565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffff000000000000000000000000000000000000000000000000000000168155600181019190915560020180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169055806119b38161557f565b915050611900565b506119c860246000614890565b60255460ff1660005b8351811015611d5f5760008482815181106119ee576119ee615550565b602002602001015190506000848381518110611a0c57611a0c615550565b602002602001015190507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148015611a8257506001846001811115611a8057611a806159d9565b145b15611ab9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82161580611af45750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611b2b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526022602052604090205467010000000000000090041615611b95576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024805460018082019092557f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec40180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8581169182179092556000818152602260209081526040918290208651815488840180518a8701805163ffffffff9095167fffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000909416841764010000000062ffffff93841602177fffffffffff0000000000000000000000000000000000000000ffffffffffffff16670100000000000000958b16959095029490941785556060808c0180519b87019b909b556080808d018051600290980180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff998a1617905589519586529351909216968401969096529251909716948101949094529551918301919091529251909216928201929092527f720a5849025dc4fd0061aed1bb30efd713cde64ce7f8d807953ecca27c8f143c9060a00160405180910390a250508080611d579061557f565b9150506119d1565b50505050565b60005b600e54811015611ddc57611dc9600e8281548110611d8857611d88615550565b600091825260209091200154601454600e5473ffffffffffffffffffffffffffffffffffffffff909216916bffffffffffffffffffffffff9091169061359a565b5080611dd48161557f565b915050611d68565b5060255460009060ff16815b600e54811015611f4d57600e8181548110611e0557611e05615550565b6000918252602082200154600d805473ffffffffffffffffffffffffffffffffffffffff9092169550600c929184908110611e4257611e42615550565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168452838201949094526040928301822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559286168152600b909252902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556001826001811115611ee457611ee46159d9565b148015611f29575073ffffffffffffffffffffffffffffffffffffffff83166000908152600b60205260409020546201000090046bffffffffffffffffffffffff1615155b15611f3b57611f39600f846124d0565b505b80611f458161557f565b915050611de8565b50611f5a600d6000614890565b611f66600e6000614890565b6040805160808101825260008082526020820181905291810182905260608101829052905b85518110156123f657600c6000878381518110611faa57611faa615550565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615612015576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1686828151811061203f5761203f615550565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603612094576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008884815181106120c5576120c5615550565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090931692909217179055845185908290811061216d5761216d615550565b60200260200101519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036121dd576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909250612298576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180835260ff80831660208086019182526014546bffffffffffffffffffffffff9081166060880190815273ffffffffffffffffffffffffffffffffffffffff8a166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909516949094171791909116929092179190911790558360018111156123d2576123d26159d9565b036123e4576123e2600f856137a2565b505b806123ee8161557f565b915050611f8b565b50845161240a90600d9060208801906148ae565b50835161241e90600e9060208701906148ae565b505050505050565b6000808a8a8a8a8a8a8a8a8a60405160200161244a99989796959493929190615a08565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b60006124f28373ffffffffffffffffffffffffffffffffffffffff84166137c4565b90505b92915050565b60006bffffffffffffffffffffffff821115612599576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016103f1565b5090565b600087876040516125af929190615a9d565b6040519081900381206125c6918b90602001615aad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b8881101561279d5760018587836020811061263257612632615550565b61263f91901a601b6156c6565b8c8c8581811061265157612651615550565b905060200201358b8b8681811061266a5761266a615550565b90506020020135604051600081526020016040526040516126a7949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156126c9573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612777576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b8401935080806127959061557f565b915050612615565b50827e010101010101010101010101010101010101010101010101010101010101018416146127f8576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61283f6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061284d83850185615b9e565b604081015151606082015151919250908114158061287057508082608001515114155b806128805750808260a001515114155b156128b7576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600082604001515167ffffffffffffffff8111156128df576128df6149bc565b6040519080825280602002602001820160405280156129ab57816020015b6040805161020081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816128fd5790505b50905060006040518060800160405280600061ffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160008152509050600085610100015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a6d9190615343565b9050600086610100015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae59190615343565b905060005b866040015151811015612f75576004600088604001518381518110612b1157612b11615550565b6020908102919091018101518252818101929092526040908101600020815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e0820152600290910154909116918101919091528551869083908110612c3457612c34615550565b602002602001015160000181905250612c6987604001518281518110612c5c57612c5c615550565b6020026020010151613813565b858281518110612c7b57612c7b615550565b6020026020010151606001906001811115612c9857612c986159d9565b90816001811115612cab57612cab6159d9565b81525050612d0f87604001518281518110612cc857612cc8615550565b60200260200101518489608001518481518110612ce757612ce7615550565b6020026020010151888581518110612d0157612d01615550565b60200260200101518c6138be565b868381518110612d2157612d21615550565b6020026020010151602001878481518110612d3e57612d3e615550565b602002602001015160c0018281525082151515158152505050848181518110612d6957612d69615550565b60200260200101516020015115612d9957600184600001818151612d8d9190615c8b565b61ffff16905250612d9e565b612f63565b612e04858281518110612db357612db3615550565b6020026020010151600001516080015188606001518381518110612dd957612dd9615550565b60200260200101518960a001518481518110612df757612df7615550565b60200260200101516139dd565b868381518110612e1657612e16615550565b6020026020010151604001878481518110612e3357612e33615550565b6020026020010151608001828152508215151515815250505087608001516001612e5d91906156c6565b612e6b9060ff166040615ca6565b6103a48860a001518381518110612e8457612e84615550565b602002602001015151612e979190615672565b612ea19190615672565b858281518110612eb357612eb3615550565b602002602001015160a0018181525050848181518110612ed557612ed5615550565b602002602001015160a0015184606001818151612ef29190615672565b9052508451859082908110612f0957612f09615550565b60200260200101516080015186612f209190615cbd565b9550612f6387604001518281518110612f3b57612f3b615550565b602002602001015184878481518110612f5657612f56615550565b6020026020010151613bf8565b80612f6d8161557f565b915050612aea565b50825161ffff16600003612f8c5750505050505050565b61c738612f9a366010615ca6565b5a612fa59088615cbd565b612faf9190615672565b612fb99190615672565b835190955061232890612fd09061ffff1687615cff565b612fda9190615672565b6040805160608101825260008082526020820181905291810182905291965061300289613cfd565b905060005b88604001515181101561333e5786818151811061302657613026615550565b6020026020010151602001511561332c578015806130be57508661304b600183615cbd565b8151811061305b5761305b615550565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1687828151811061309457613094615550565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1614155b156130f2576130ef8a8883815181106130d9576130d9615550565b6020026020010151600001516101000151613dee565b92505b60006132108b6040518061012001604052808b868151811061311657613116615550565b60200260200101516080015181526020018c81526020018a606001518c878151811061314457613144615550565b602002602001015160a001518a61315b9190615ca6565b6131659190615cff565b81526020018d6000015181526020018d6020015181526020018681526020018b868151811061319657613196615550565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff168152602001878152602001600115158152508c6040015185815181106131e5576131e5615550565b60200260200101518b86815181106131ff576131ff615550565b602002602001015160000151613f3f565b9050806060015187604001818151613228919061564d565b6bffffffffffffffffffffffff16905250604081015160208801805161324f90839061564d565b6bffffffffffffffffffffffff16905250875188908390811061327457613274615550565b60200260200101516040015115158a60400151838151811061329857613298615550565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b836060015184604001516132d5919061564d565b8b86815181106132e7576132e7615550565b6020026020010151608001518d8f60800151888151811061330a5761330a615550565b60200260200101516040516133229493929190615d13565b60405180910390a3505b806133368161557f565b915050613007565b505050602083810151336000908152600b9092526040909120805460029061337b9084906201000090046bffffffffffffffffffffffff1661564d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151601460000160008282829054906101000a90046bffffffffffffffffffffffff166133d9919061564d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151836020015161341b919061564d565b6bffffffffffffffffffffffff16602160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546134979190615672565b909155505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613524576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906137965760008160600151856136329190615d50565b905060006136408583615d75565b90508083604001818151613654919061564d565b6bffffffffffffffffffffffff1690525061366f8582615da0565b83606001818151613680919061564d565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b60006124f28373ffffffffffffffffffffffffffffffffffffffff841661423b565b600081815260018301602052604081205461380b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556124f5565b5060006124f5565b6000818160045b600f8110156138a0577fff00000000000000000000000000000000000000000000000000000000000000821683826020811061385857613858615550565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461388e57506000949350505050565b806138988161557f565b91505061381a565b5081600f1a60018111156138b6576138b66159d9565b949350505050565b6000808080856060015160018111156138d9576138d96159d9565b036138ff576138eb888888888861432e565b6138fa576000925090506139d3565b613977565b600185606001516001811115613917576139176159d9565b0361394557600061392a898989886144b8565b925090508061393f57506000925090506139d3565b50613977565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516060015163ffffffff1687106139cc57877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516139b991906149a9565b60405180910390a26000925090506139d3565b6001925090505b9550959350505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff1615613a3a576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090613aaf9085906024016149a9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d1690613b829087908790600401615dd0565b60408051808303816000875af1158015613ba0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bc49190615de9565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b600081606001516001811115613c1057613c106159d9565b03613c7457600083815260046020526040902060010180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff851602179055505050565b600181606001516001811115613c8c57613c8c6159d9565b03613cf85760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613d6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d919190615e31565b50935050925050600082131580613da757508042105b80613dd757506000846040015162ffffff16118015613dd75750613dcb8142615cbd565b846040015162ffffff16105b15613de7575050601b5492915050565b5092915050565b604080516060810182526000808252602080830182815283850183905273ffffffffffffffffffffffffffffffffffffffff868116845260229092528483208054640100000000810462ffffff1690925263ffffffff8216855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495909484936701000000000000009093049092169163feaf968c9160048082019260a0929091908290030181865afa158015613eb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ed49190615e31565b50935050925050600082131580613eea57508042105b80613f1a57506000866040015162ffffff16118015613f1a5750613f0e8142615cbd565b866040015162ffffff16105b15613f2e5760018301546040850152613f36565b604084018290525b50505092915050565b604080516080810182526000808252602080830182905292820181905260608201529082015115613fb85760008381526023602090815260409182902082518084019093525463ffffffff811680845262ffffff640100000000909204821693830193845260e088018051919091529251925192169101525b6000613fc486866146c5565b60c0840151602082015182519293509091600091613fe19161564d565b905082600001516bffffffffffffffffffffffff16826bffffffffffffffffffffffff1610156140665781905061404787608001518860e0015160400151846bffffffffffffffffffffffff166140389190615ca6565b6140429190615cff565b6124fb565b6bffffffffffffffffffffffff166040840152600060608401526140f2565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff1610156140f2578190506140de83604001516bffffffffffffffffffffffff1688608001518960e0015160400151856bffffffffffffffffffffffff166140ca9190615ca6565b6140d49190615cff565b6140429190615cbd565b6bffffffffffffffffffffffff1660608401525b6000868152600460205260409020600101805482919060109061413890849070010000000000000000000000000000000090046bffffffffffffffffffffffff16615d50565b82546101009290920a6bffffffffffffffffffffffff818102199093169183160217909155600088815260046020526040812060010180549285169350916141939084906fffffffffffffffffffffffffffffffff16615e81565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550806bffffffffffffffffffffffff16602160008960c0015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461422a9190615cbd565b909155509298975050505050505050565b6000818152600183016020526040812054801561432457600061425f600183615cbd565b855490915060009061427390600190615cbd565b90508181146142d857600086600001828154811061429357614293615550565b90600052602060002001549050808760000184815481106142b6576142b6615550565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806142e9576142e9615eaa565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506124f5565b60009150506124f5565b600080848060200190518101906143459190615ed9565b845160e00151815191925063ffffffff908116911610156143a257867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88660405161439091906149a9565b60405180910390a260009150506144af565b8260e00151801561446257506020810151158015906144625750602081015161010084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa15801561443b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061445f9190615343565b14155b806144745750805163ffffffff168611155b156144a957867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018660405161439091906149a9565b60019150505b95945050505050565b6000806000848060200190518101906144d19190615f31565b905060008782600001518360200151846040015160405160200161453394939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508460e00151801561460e575060808201511580159061460e5750608082015161010086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa1580156145e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061460b9190615343565b14155b80614623575086826060015163ffffffff1610155b1561466d57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018760405161465891906149a9565b60405180910390a26000935091506146bc9050565b60008181526008602052604090205460ff16156146b457877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88760405161465891906149a9565b600193509150505b94509492505050565b6040805160808101825260008082526020820181905291810182905260608101919091526000836060015161ffff1683606001516147039190615ca6565b905082610100015180156147165750803a105b1561471e57503a5b60008360a0015184604001518560200151866000015161473e9190615672565b6147489085615ca6565b6147529190615672565b61475c9190615ca6565b90506147758460e0015160400151826140429190615cff565b6bffffffffffffffffffffffff1683526080840151614798906140429083615cff565b6bffffffffffffffffffffffff16604084015260e0840151602001516000906147cf9062ffffff16683635c9adc5dea00000615ca6565b9050600081633b9aca008760a001518860e001516000015163ffffffff1689604001518a60000151896148029190615ca6565b61480c9190615672565b6148169190615ca6565b6148209190615ca6565b61482a9190615cff565b6148349190615672565b905061484d8660e0015160400151826140429190615cff565b6bffffffffffffffffffffffff1660208601526080860151614873906140429083615cff565b6bffffffffffffffffffffffff1660608601525050505092915050565b50805460008255906000526020600020908101906118779190614930565b828054828255906000526020600020908101928215614928579160200282015b8281111561492857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906148ce565b506125999291505b5b808211156125995760008155600101614931565b6000815180845260005b8181101561496b5760208185018101518683018201520161494f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006124f26020830184614945565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff81118282101715614a0f57614a0f6149bc565b60405290565b60405160a0810167ffffffffffffffff81118282101715614a0f57614a0f6149bc565b60405160c0810167ffffffffffffffff81118282101715614a0f57614a0f6149bc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614aa257614aa26149bc565b604052919050565b600067ffffffffffffffff821115614ac457614ac46149bc565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461187757600080fd5b8035614afb81614ace565b919050565b600082601f830112614b1157600080fd5b81356020614b26614b2183614aaa565b614a5b565b82815260059290921b84018101918181019086841115614b4557600080fd5b8286015b84811015614b69578035614b5c81614ace565b8352918301918301614b49565b509695505050505050565b803560ff81168114614afb57600080fd5b63ffffffff8116811461187757600080fd5b8035614afb81614b85565b801515811461187757600080fd5b8035614afb81614ba2565b62ffffff8116811461187757600080fd5b8035614afb81614bbb565b61ffff8116811461187757600080fd5b8035614afb81614bd7565b60006102008284031215614c0557600080fd5b614c0d6149eb565b9050614c1882614b97565b8152614c2660208301614b97565b6020820152614c3760408301614b97565b6040820152614c4860608301614af0565b6060820152614c5960808301614bb0565b6080820152614c6a60a08301614bcc565b60a0820152614c7b60c08301614b97565b60c0820152614c8c60e08301614b97565b60e0820152610100614c9f818401614af0565b90820152610120614cb1838201614be7565b90820152610140614cc3838201614af0565b90820152610160828101359082015261018080830135908201526101a080830135908201526101c08083013567ffffffffffffffff811115614d0457600080fd5b614d1085828601614b00565b8284015250506101e0614d24818401614af0565b9082015292915050565b803567ffffffffffffffff81168114614afb57600080fd5b600082601f830112614d5757600080fd5b813567ffffffffffffffff811115614d7157614d716149bc565b614da260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a5b565b818152846020838601011115614db757600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112614de557600080fd5b81356020614df5614b2183614aaa565b82815260059290921b84018101918181019086841115614e1457600080fd5b8286015b84811015614b69578035614e2b81614ace565b8352918301918301614e18565b6bffffffffffffffffffffffff8116811461187757600080fd5b600082601f830112614e6357600080fd5b81356020614e73614b2183614aaa565b82815260a09283028501820192828201919087851115614e9257600080fd5b8387015b85811015614f115781818a031215614eae5760008081fd5b614eb6614a15565b8135614ec181614b85565b815281860135614ed081614bbb565b81870152604082810135614ee381614ace565b9082015260608281013590820152608080830135614f0081614e38565b908201528452928401928101614e96565b5090979650505050505050565b600080600080600080600080610100898b031215614f3b57600080fd5b883567ffffffffffffffff80821115614f5357600080fd5b614f5f8c838d01614b00565b995060208b0135915080821115614f7557600080fd5b614f818c838d01614b00565b9850614f8f60408c01614b74565b975060608b0135915080821115614fa557600080fd5b614fb18c838d01614bf2565b9650614fbf60808c01614d2e565b955060a08b0135915080821115614fd557600080fd5b614fe18c838d01614d46565b945060c08b0135915080821115614ff757600080fd5b6150038c838d01614dd4565b935060e08b013591508082111561501957600080fd5b506150268b828c01614e52565b9150509295985092959890939650565b6000806040838503121561504957600080fd5b82359150602083013561505b81614e38565b809150509250929050565b60008083601f84011261507857600080fd5b50813567ffffffffffffffff81111561509057600080fd5b6020830191508360208285010111156150a857600080fd5b9250929050565b600080600080606085870312156150c557600080fd5b84356150d081614ace565b935060208501359250604085013567ffffffffffffffff8111156150f357600080fd5b6150ff87828801615066565b95989497509550505050565b60008083601f84011261511d57600080fd5b50813567ffffffffffffffff81111561513557600080fd5b6020830191508360208260051b85010111156150a857600080fd5b60008060008060008060008060e0898b03121561516c57600080fd5b606089018a81111561517d57600080fd5b8998503567ffffffffffffffff8082111561519757600080fd5b6151a38c838d01615066565b909950975060808b01359150808211156151bc57600080fd5b6151c88c838d0161510b565b909750955060a08b01359150808211156151e157600080fd5b506151ee8b828c0161510b565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c0878903121561522057600080fd5b863567ffffffffffffffff8082111561523857600080fd5b6152448a838b01614b00565b9750602089013591508082111561525a57600080fd5b6152668a838b01614b00565b965061527460408a01614b74565b9550606089013591508082111561528a57600080fd5b6152968a838b01614d46565b94506152a460808a01614d2e565b935060a08901359150808211156152ba57600080fd5b506152c789828a01614d46565b9150509295509295509295565b6000602082840312156152e657600080fd5b81356152f181614ace565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160290811690818114613de757613de76152f8565b60006020828403121561535557600080fd5b5051919050565b63ffffffff818116838216019080821115613de757613de76152f8565b600081518084526020808501945080840160005b838110156153bf57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161538d565b509495945050505050565b602081526153e160208201835163ffffffff169052565b600060208301516153fa604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006154798185018363ffffffff169052565b84015190506101206154a28482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015190506101406154b98482018361ffff169052565b84015190506101606154e28482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e08086018290529192509061552a610220860184615379565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036155b0576155b06152f8565b5060010190565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526155e78184018a615379565b905082810360808401526155fb8189615379565b905060ff871660a084015282810360c08401526156188187614945565b905067ffffffffffffffff851660e084015282810361010084015261563d8185614945565b9c9b505050505050505050505050565b6bffffffffffffffffffffffff818116838216019080821115613de757613de76152f8565b808201808211156124f5576124f56152f8565b8051614afb81614ba2565b6000602082840312156156a257600080fd5b81516152f181614ba2565b6000602082840312156156bf57600080fd5b5035919050565b60ff81811683821601908111156124f5576124f56152f8565b8051614afb81614b85565b8051614afb81614ace565b8051614afb81614bbb565b8051614afb81614bd7565b600082601f83011261571c57600080fd5b8151602061572c614b2183614aaa565b82815260059290921b8401810191818101908684111561574b57600080fd5b8286015b84811015614b6957805161576281614ace565b835291830191830161574f565b600082601f83011261578057600080fd5b81516020615790614b2183614aaa565b82815260a092830285018201928282019190878511156157af57600080fd5b8387015b85811015614f115781818a0312156157cb5760008081fd5b6157d3614a15565b81516157de81614b85565b8152818601516157ed81614bbb565b8187015260408281015161580081614ace565b908201526060828101519082015260808083015161581d81614e38565b9082015284529284019281016157b3565b60008060006060848603121561584357600080fd5b835167ffffffffffffffff8082111561585b57600080fd5b90850190610200828803121561587057600080fd5b6158786149eb565b615881836156df565b815261588f602084016156df565b60208201526158a0604084016156df565b60408201526158b1606084016156ea565b60608201526158c260808401615685565b60808201526158d360a084016156f5565b60a08201526158e460c084016156df565b60c08201526158f560e084016156df565b60e08201526101006159088185016156ea565b9082015261012061591a848201615700565b9082015261014061592c8482016156ea565b90820152610160838101519082015261018080840151908201526101a080840151908201526101c0808401518381111561596557600080fd5b6159718a82870161570b565b8284015250506101e06159858185016156ea565b9082015260208701519095509150808211156159a057600080fd5b6159ac8783880161570b565b935060408601519150808211156159c257600080fd5b506159cf8682870161576f565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152615a4f8285018b615379565b91508382036080850152615a63828a615379565b915060ff881660a085015283820360c0850152615a808288614945565b90861660e0850152838103610100850152905061563d8185614945565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112615ad457600080fd5b81356020615ae4614b2183614aaa565b82815260059290921b84018101918181019086841115615b0357600080fd5b8286015b84811015614b695780358352918301918301615b07565b600082601f830112615b2f57600080fd5b81356020615b3f614b2183614aaa565b82815260059290921b84018101918181019086841115615b5e57600080fd5b8286015b84811015614b6957803567ffffffffffffffff811115615b825760008081fd5b615b908986838b0101614d46565b845250918301918301615b62565b600060208284031215615bb057600080fd5b813567ffffffffffffffff80821115615bc857600080fd5b9083019060c08286031215615bdc57600080fd5b615be4614a38565b8235815260208301356020820152604083013582811115615c0457600080fd5b615c1087828601615ac3565b604083015250606083013582811115615c2857600080fd5b615c3487828601615ac3565b606083015250608083013582811115615c4c57600080fd5b615c5887828601615b1e565b60808301525060a083013582811115615c7057600080fd5b615c7c87828601615b1e565b60a08301525095945050505050565b61ffff818116838216019080821115613de757613de76152f8565b80820281158282048414176124f5576124f56152f8565b818103818111156124f5576124f56152f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615d0e57615d0e615cd0565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000615d466080830184614945565b9695505050505050565b6bffffffffffffffffffffffff828116828216039080821115613de757613de76152f8565b60006bffffffffffffffffffffffff80841680615d9457615d94615cd0565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114615dc857615dc86152f8565b505092915050565b8281526040602082015260006138b66040830184614945565b60008060408385031215615dfc57600080fd5b8251615e0781614ba2565b6020939093015192949293505050565b805169ffffffffffffffffffff81168114614afb57600080fd5b600080600080600060a08688031215615e4957600080fd5b615e5286615e17565b9450602086015193506040860151925060608601519150615e7560808701615e17565b90509295509295909350565b6fffffffffffffffffffffffffffffffff818116838216019080821115613de757613de76152f8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215615eeb57600080fd5b6040516040810181811067ffffffffffffffff82111715615f0e57615f0e6149bc565b6040528251615f1c81614b85565b81526020928301519281019290925250919050565b600060a08284031215615f4357600080fd5b615f4b614a15565b82518152602083015160208201526040830151615f6781614b85565b60408201526060830151615f7a81614b85565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicA2_3\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+ Bin: "0x6101806040523480156200001257600080fd5b50604051620065e2380380620065e283398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051615eae620007346000396000818160be015261019101526000505060005050600050506000505060006139a301526000505060008181610db101528181610ebf01528181610fea01528181611034015281816116b601526130ce0152615eae6000f3fe6080604052600436106100bc5760003560e01c80638da5cb5b11610074578063b1dc65a41161004e578063b1dc65a4146102f6578063e3d0e71214610316578063f2fde38b14610336576100bc565b80638da5cb5b14610265578063a4c0ed3614610290578063afcb95d7146102b0576100bc565b8063349e8cca116100a5578063349e8cca1461018257806379ba5097146101d657806381ff7048146101eb576100bc565b80630870d3a114610103578063181f5a7714610123575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100fc573d6000f35b3d6000fd5b005b34801561010f57600080fd5b5061010161011e366004614c23565b610356565b34801561012f57600080fd5b5061016c6040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b6040516101799190614d9f565b60405180910390f35b34801561018e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610179565b3480156101e257600080fd5b50610101610c97565b3480156101f757600080fd5b5061024260175460135463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610179565b34801561027157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101b1565b34801561029c57600080fd5b506101016102ab366004614dfb565b610d99565b3480156102bc57600080fd5b50601354601454604080516000815260208101939093526c0100000000000000000000000090910463ffffffff1690820152606001610179565b34801561030257600080fd5b50610101610311366004614e9c565b6110b5565b34801561032257600080fd5b50610101610331366004614f53565b611396565b34801561034257600080fd5b50610101610351366004615020565b6113d0565b61035e6113e4565b601f8851111561039a576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560ff166000036103d7576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865188511415806103f657506103ee866003615073565b60ff16885111155b1561042d576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051825114610468576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104728282611467565b61047c8888611a9f565b604051806101200160405280601460000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001600063ffffffff1681526020018660a0015162ffffff16815260200186610120015161ffff1681526020018760ff168152602001601460000160169054906101000a900460ff1615158152602001601460000160179054906101000a900460ff1615158152602001866080015115158152602001866101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548162ffffff021916908362ffffff16021790555060608201518160000160136101000a81548161ffff021916908361ffff16021790555060808201518160000160156101000a81548160ff021916908360ff16021790555060a08201518160000160166101000a81548160ff02191690831515021790555060c08201518160000160176101000a81548160ff02191690831515021790555060e08201518160000160186101000a81548160ff0219169083151502179055506101008201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050604051806101600160405280866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866000015163ffffffff168152602001866020015163ffffffff1681526020016016600001601c9054906101000a900463ffffffff1663ffffffff16815260200186610100015173ffffffffffffffffffffffffffffffffffffffff168152602001601660010160149054906101000a900463ffffffff1663ffffffff168152602001601660010160189054906101000a900463ffffffff1663ffffffff168152602001866040015163ffffffff16815260200186610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018660c0015163ffffffff1681526020018660e0015163ffffffff16815250601660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160186101000a81548163ffffffff021916908363ffffffff160217905550905050846101600151601981905550846101800151601a81905550846101a00151601b819055506000601660010160189054906101000a900463ffffffff169050856101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa6919061508f565b601780547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601491610b1d918591740100000000000000000000000000000000000000009004166150a8565b92506101000a81548163ffffffff021916908363ffffffff160217905550600086604051602001610b4e9190615116565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601754909150610bb3904690309074010000000000000000000000000000000000000000900463ffffffff168d8d8d878d8d612160565b601355600960008181610bc68282614677565b5050505060005b876101c0015151811015610c2057610c0d886101c001518281518110610bf557610bf561529c565b6020026020010151600961220a90919063ffffffff16565b5080610c18816152cb565b915050610bcd565b506013546017546040517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0592610c839286927401000000000000000000000000000000000000000090910463ffffffff16908f908f908f9089908f908f90615303565b60405180910390a150505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610e08576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114610e42576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e5082840184615399565b6000818152600460205260409020549091506601000000000000900463ffffffff90811614610eab576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600201547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614610f2f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260046020526040902060010154610f6e90859070010000000000000000000000000000000090046bffffffffffffffffffffffff166153b2565b600082815260046020908152604080832060010180546bffffffffffffffffffffffff95909516700100000000000000000000000000000000027fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff9095169490941790935573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016825260219052205461101d9085906153d7565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660009081526021602090815260409182902093909355516bffffffffffffffffffffffff871681529087169183917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203910160405180910390a35050505050565b60005a60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff75010000000000000000000000000000000000000000008304811660808301527601000000000000000000000000000000000000000000008304811615801560a08401527701000000000000000000000000000000000000000000000084048216151560c0840152780100000000000000000000000000000000000000000000000090930416151560e082015260155473ffffffffffffffffffffffffffffffffffffffff16610100820152919250611219576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16611262576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013548a351461129e576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60808101516112ae9060016153ea565b60ff16861415806112bf5750858414155b156112f6576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113068a8a8a8a8a8a8a8a612235565b60006113128a8a61249e565b905060208b0135600881901c63ffffffff1661132f848487612557565b836020015163ffffffff168163ffffffff16111561138757601480547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b6000806000858060200190518101906113af91906155d4565b9250925092506113c58989898689898888610356565b505050505050505050565b6113d86113e4565b6113e181613144565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d14565b565b60005b60245481101561152557602260006024838154811061148b5761148b61529c565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffff00000000000000000000000000000000000000000000000000000000168155600181019190915560020180547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690558061151d816152cb565b91505061146a565b5061153260246000614677565b60255460ff1660005b8351811015611a995760008482815181106115585761155861529c565b6020026020010151905060008483815181106115765761157661529c565b602002602001015190508173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ef919061577f565b60ff16816060015160ff1614158061167d5750806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611651573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611675919061577f565b60ff16600814155b156116b4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480156117205750600184600181111561171e5761171e61579c565b145b15611757576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821615806117925750604081015173ffffffffffffffffffffffffffffffffffffffff16155b156117c9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526022602052604090205467010000000000000090041615611833576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024805460018181019092557f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec401805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216821790925560008181526022602090815260409182902086518154928801518489015160608a015160ff167b01000000000000000000000000000000000000000000000000000000027fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff9190981667010000000000000002167fffffffff000000000000000000000000000000000000000000ffffffffffffff62ffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000090951663ffffffff9093169290921793909317929092169190911793909317835560808501519383019390935560a0840151600290920180546bffffffffffffffffffffffff9093167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009093169290921790915590517fca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba390611a7c908490600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b60405180910390a250508080611a91906152cb565b91505061153b565b50505050565b60005b600e54811015611b1657611b03600e8281548110611ac257611ac261529c565b600091825260209091200154601454600e5473ffffffffffffffffffffffffffffffffffffffff909216916bffffffffffffffffffffffff90911690613239565b5080611b0e816152cb565b915050611aa2565b5060255460009060ff16815b600e54811015611c8757600e8181548110611b3f57611b3f61529c565b6000918252602082200154600d805473ffffffffffffffffffffffffffffffffffffffff9092169550600c929184908110611b7c57611b7c61529c565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168452838201949094526040928301822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559286168152600b909252902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556001826001811115611c1e57611c1e61579c565b148015611c63575073ffffffffffffffffffffffffffffffffffffffff83166000908152600b60205260409020546201000090046bffffffffffffffffffffffff1615155b15611c7557611c73600f8461220a565b505b80611c7f816152cb565b915050611b22565b50611c94600d6000614677565b611ca0600e6000614677565b6040805160808101825260008082526020820181905291810182905260608101829052905b855181101561213057600c6000878381518110611ce457611ce461529c565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611d4f576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16868281518110611d7957611d7961529c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611dce576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c6000888481518110611dff57611dff61529c565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558451859082908110611ea757611ea761529c565b60200260200101519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611f17576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909250611fd2576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180835260ff80831660208086019182526014546bffffffffffffffffffffffff9081166060880190815273ffffffffffffffffffffffffffffffffffffffff8a166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905583600181111561210c5761210c61579c565b0361211e5761211c600f85613441565b505b80612128816152cb565b915050611cc5565b50845161214490600d906020880190614695565b50835161215890600e906020870190614695565b505050505050565b6000808a8a8a8a8a8a8a8a8a604051602001612184999897969594939291906157cb565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b600061222c8373ffffffffffffffffffffffffffffffffffffffff8416613463565b90505b92915050565b60008787604051612247929190615860565b60405190819003812061225e918b90602001615870565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612435576001858783602081106122ca576122ca61529c565b6122d791901a601b6153ea565b8c8c858181106122e9576122e961529c565b905060200201358b8b868181106123025761230261529c565b905060200201356040516000815260200160405260405161233f949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612361573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff808216151580855261010090920416938301939093529095509350905061240f576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061242d906152cb565b9150506122ad565b50827e01010101010101010101010101010101010101010101010101010101010101841614612490576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6124d76040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b60006124e583850185615961565b604081015151606082015151919250908114158061250857508082608001515114155b806125185750808260a001515114155b1561254f576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600082604001515167ffffffffffffffff8111156125775761257761472c565b60405190808252806020026020018201604052801561264357816020015b6040805161020081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816125955790505b50905060006040518060800160405280600061ffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160008152509050600085610100015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612705919061508f565b9050600086610100015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015612759573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277d919061508f565b905060005b866040015151811015612c0d5760046000886040015183815181106127a9576127a961529c565b6020908102919091018101518252818101929092526040908101600020815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915285518690839081106128cc576128cc61529c565b602002602001015160000181905250612901876040015182815181106128f4576128f461529c565b60200260200101516134b2565b8582815181106129135761291361529c565b60200260200101516060019060018111156129305761293061579c565b908160018111156129435761294361579c565b815250506129a7876040015182815181106129605761296061529c565b6020026020010151848960800151848151811061297f5761297f61529c565b60200260200101518885815181106129995761299961529c565b60200260200101518c61355d565b8683815181106129b9576129b961529c565b60200260200101516020018784815181106129d6576129d661529c565b602002602001015160c0018281525082151515158152505050848181518110612a0157612a0161529c565b60200260200101516020015115612a3157600184600001818151612a259190615a4e565b61ffff16905250612a36565b612bfb565b612a9c858281518110612a4b57612a4b61529c565b6020026020010151600001516080015188606001518381518110612a7157612a7161529c565b60200260200101518960a001518481518110612a8f57612a8f61529c565b602002602001015161367c565b868381518110612aae57612aae61529c565b6020026020010151604001878481518110612acb57612acb61529c565b6020026020010151608001828152508215151515815250505087608001516001612af591906153ea565b612b039060ff166040615a69565b6103a48860a001518381518110612b1c57612b1c61529c565b602002602001015151612b2f91906153d7565b612b3991906153d7565b858281518110612b4b57612b4b61529c565b602002602001015160a0018181525050848181518110612b6d57612b6d61529c565b602002602001015160a0015184606001818151612b8a91906153d7565b9052508451859082908110612ba157612ba161529c565b60200260200101516080015186612bb89190615a80565b9550612bfb87604001518281518110612bd357612bd361529c565b602002602001015184878481518110612bee57612bee61529c565b6020026020010151613897565b80612c05816152cb565b915050612782565b50825161ffff16600003612c245750505050505050565b61c800612c32366010615a69565b5a612c3d9088615a80565b612c4791906153d7565b612c5191906153d7565b83519095506123f090612c689061ffff1687615ac2565b612c7291906153d7565b6040805160808101825260008082526020820181905291810182905260608101829052919650612ca18961399c565b905060005b886040015151811015612fdd57868181518110612cc557612cc561529c565b60200260200101516020015115612fcb57801580612d5d575086612cea600183615a80565b81518110612cfa57612cfa61529c565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff16878281518110612d3357612d3361529c565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1614155b15612d9157612d8e8a888381518110612d7857612d7861529c565b6020026020010151600001516101000151613a8d565b92505b6000612eaf8b6040518061012001604052808b8681518110612db557612db561529c565b60200260200101516080015181526020018c81526020018a606001518c8781518110612de357612de361529c565b602002602001015160a001518a612dfa9190615a69565b612e049190615ac2565b81526020018d6000015181526020018d6020015181526020018681526020018b8681518110612e3557612e3561529c565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff168152602001878152602001600115158152508c604001518581518110612e8457612e8461529c565b60200260200101518b8681518110612e9e57612e9e61529c565b602002602001015160000151613c09565b9050806060015187604001818151612ec791906153b2565b6bffffffffffffffffffffffff169052506040810151602088018051612eee9083906153b2565b6bffffffffffffffffffffffff169052508751889083908110612f1357612f1361529c565b60200260200101516040015115158a604001518381518110612f3757612f3761529c565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b83606001518460400151612f7491906153b2565b8b8681518110612f8657612f8661529c565b6020026020010151608001518d8f608001518881518110612fa957612fa961529c565b6020026020010151604051612fc19493929190615ad6565b60405180910390a3505b80612fd5816152cb565b915050612ca6565b505050602083810151336000908152600b9092526040909120805460029061301a9084906201000090046bffffffffffffffffffffffff166153b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151601460000160008282829054906101000a90046bffffffffffffffffffffffff1661307891906153b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550826040015183602001516130ba91906153b2565b6bffffffffffffffffffffffff16602160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461313691906153d7565b909155505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036131c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d14565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906134355760008160600151856132d19190615b13565b905060006132df8583615b38565b905080836040018181516132f391906153b2565b6bffffffffffffffffffffffff1690525061330e8582615b63565b8360600181815161331f91906153b2565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b600061222c8373ffffffffffffffffffffffffffffffffffffffff8416613f05565b60008181526001830160205260408120546134aa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561222f565b50600061222f565b6000818160045b600f81101561353f577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106134f7576134f761529c565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461352d57506000949350505050565b80613537816152cb565b9150506134b9565b5081600f1a60018111156135555761355561579c565b949350505050565b6000808080856060015160018111156135785761357861579c565b0361359e5761358a8888888888613ff8565b61359957600092509050613672565b613616565b6001856060015160018111156135b6576135b661579c565b036135e45760006135c989898988614182565b92509050806135de5750600092509050613672565b50613616565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516060015163ffffffff16871061366b57877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516136589190614d9f565b60405180910390a2600092509050613672565b6001925090505b9550959350505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff16156136d9576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061374e908590602401614d9f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906138219087908790600401615b93565b60408051808303816000875af115801561383f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138639190615bac565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b6000816060015160018111156138af576138af61579c565b0361391357600083815260046020526040902060010180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff851602179055505050565b60018160600151600181111561392b5761392b61579c565b036139975760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613a0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a309190615bf4565b50935050925050600082131580613a4657508042105b80613a7657506000846040015162ffffff16118015613a765750613a6a8142615a80565b846040015162ffffff16105b15613a86575050601b5492915050565b5092915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015613b7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9e9190615bf4565b50935050925050600082131580613bb457508042105b80613be457506000866040015162ffffff16118015613be45750613bd88142615a80565b866040015162ffffff16105b15613bf85760018301546060850152613c00565b606084018290525b50505092915050565b604080516080810182526000808252602080830182905292820181905260608201529082015115613c825760008381526023602090815260409182902082518084018452905463ffffffff811680835262ffffff640100000000909204821692840192835260e089018051909401529051915191169101525b6000613c8e868661438f565b60c0840151602082015182519293509091600091613cab916153b2565b905082600001516bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613d3057819050613d1187608001518860e0015160600151846bffffffffffffffffffffffff16613d029190615a69565b613d0c9190615ac2565b6145d5565b6bffffffffffffffffffffffff16604084015260006060840152613dbc565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613dbc57819050613da883604001516bffffffffffffffffffffffff1688608001518960e0015160600151856bffffffffffffffffffffffff16613d949190615a69565b613d9e9190615ac2565b613d0c9190615a80565b6bffffffffffffffffffffffff1660608401525b60008681526004602052604090206001018054829190601090613e0290849070010000000000000000000000000000000090046bffffffffffffffffffffffff16615b13565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008881526004602052604081206001018054928516935091613e5d9084906fffffffffffffffffffffffffffffffff16615c44565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550806bffffffffffffffffffffffff16602160008960c0015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613ef49190615a80565b909155509298975050505050505050565b60008181526001830160205260408120548015613fee576000613f29600183615a80565b8554909150600090613f3d90600190615a80565b9050818114613fa2576000866000018281548110613f5d57613f5d61529c565b9060005260206000200154905080876000018481548110613f8057613f8061529c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613fb357613fb3615c6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061222f565b600091505061222f565b6000808480602001905181019061400f9190615c9c565b845160e00151815191925063ffffffff9081169116101561406c57867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88660405161405a9190614d9f565b60405180910390a26000915050614179565b8260e00151801561412c575060208101511580159061412c5750602081015161010084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015614105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614129919061508f565b14155b8061413e5750805163ffffffff168611155b1561417357867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018660405161405a9190614d9f565b60019150505b95945050505050565b60008060008480602001905181019061419b9190615cf4565b90506000878260000151836020015184604001516040516020016141fd94939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508460e0015180156142d857506080820151158015906142d85750608082015161010086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa1580156142b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142d5919061508f565b14155b806142ed575086826060015163ffffffff1610155b1561433757877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516143229190614d9f565b60405180910390a26000935091506143869050565b60008181526008602052604090205460ff161561437e57877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516143229190614d9f565b600193509150505b94509492505050565b60408051608081018252600080825260208201819052918101829052606081019190915260008260e001516000015160ff1690506000846060015161ffff1684606001516143dd9190615a69565b905083610100015180156143f05750803a105b156143f857503a5b60006012831161440957600161441f565b614414601284615a80565b61441f90600a615e95565b9050600060128410614432576001614448565b61443d846012615a80565b61444890600a615e95565b905060008660a0015187604001518860200151896000015161446a91906153d7565b6144749087615a69565b61447e91906153d7565b6144889190615a69565b90506144ab828860e00151606001516144a19190615a69565b613d028584615a69565b6bffffffffffffffffffffffff16865260808701516144ce90613d0c9083615ac2565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906145079062ffffff16683635c9adc5dea00000615a69565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b61453a9190615a69565b61454491906153d7565b61454e9190615a69565b6145589190615a69565b6145629190615ac2565b61456c91906153d7565b905061458f848a60e00151606001516145859190615a69565b613d028784615a69565b6bffffffffffffffffffffffff16602089015260808901516145b590613d0c9083615ac2565b6bffffffffffffffffffffffff1660608901525050505050505092915050565b60006bffffffffffffffffffffffff821115614673576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610d14565b5090565b50805460008255906000526020600020908101906113e19190614717565b82805482825590600052602060002090810192821561470f579160200282015b8281111561470f57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906146b5565b506146739291505b5b808211156146735760008155600101614718565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff8111828210171561477f5761477f61472c565b60405290565b60405160c0810167ffffffffffffffff8111828210171561477f5761477f61472c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156147ef576147ef61472c565b604052919050565b600067ffffffffffffffff8211156148115761481161472c565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146113e157600080fd5b80356148488161481b565b919050565b600082601f83011261485e57600080fd5b8135602061487361486e836147f7565b6147a8565b82815260059290921b8401810191818101908684111561489257600080fd5b8286015b848110156148b65780356148a98161481b565b8352918301918301614896565b509695505050505050565b60ff811681146113e157600080fd5b8035614848816148c1565b63ffffffff811681146113e157600080fd5b8035614848816148db565b80151581146113e157600080fd5b8035614848816148f8565b62ffffff811681146113e157600080fd5b803561484881614911565b61ffff811681146113e157600080fd5b80356148488161492d565b6000610200828403121561495b57600080fd5b61496361475b565b905061496e826148ed565b815261497c602083016148ed565b602082015261498d604083016148ed565b604082015261499e6060830161483d565b60608201526149af60808301614906565b60808201526149c060a08301614922565b60a08201526149d160c083016148ed565b60c08201526149e260e083016148ed565b60e08201526101006149f581840161483d565b90820152610120614a0783820161493d565b90820152610140614a1983820161483d565b90820152610160828101359082015261018080830135908201526101a080830135908201526101c08083013567ffffffffffffffff811115614a5a57600080fd5b614a668582860161484d565b8284015250506101e0614a7a81840161483d565b9082015292915050565b803567ffffffffffffffff8116811461484857600080fd5b600082601f830112614aad57600080fd5b813567ffffffffffffffff811115614ac757614ac761472c565b614af860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016147a8565b818152846020838601011115614b0d57600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff811681146113e157600080fd5b600082601f830112614b5557600080fd5b81356020614b6561486e836147f7565b82815260c09283028501820192828201919087851115614b8457600080fd5b8387015b85811015614c165781818a031215614ba05760008081fd5b614ba8614785565b8135614bb3816148db565b815281860135614bc281614911565b81870152604082810135614bd58161481b565b90820152606082810135614be8816148c1565b908201526080828101359082015260a080830135614c0581614b2a565b908201528452928401928101614b88565b5090979650505050505050565b600080600080600080600080610100898b031215614c4057600080fd5b883567ffffffffffffffff80821115614c5857600080fd5b614c648c838d0161484d565b995060208b0135915080821115614c7a57600080fd5b614c868c838d0161484d565b9850614c9460408c016148d0565b975060608b0135915080821115614caa57600080fd5b614cb68c838d01614948565b9650614cc460808c01614a84565b955060a08b0135915080821115614cda57600080fd5b614ce68c838d01614a9c565b945060c08b0135915080821115614cfc57600080fd5b614d088c838d0161484d565b935060e08b0135915080821115614d1e57600080fd5b50614d2b8b828c01614b44565b9150509295985092959890939650565b6000815180845260005b81811015614d6157602081850181015186830182015201614d45565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061222c6020830184614d3b565b60008083601f840112614dc457600080fd5b50813567ffffffffffffffff811115614ddc57600080fd5b602083019150836020828501011115614df457600080fd5b9250929050565b60008060008060608587031215614e1157600080fd5b8435614e1c8161481b565b935060208501359250604085013567ffffffffffffffff811115614e3f57600080fd5b614e4b87828801614db2565b95989497509550505050565b60008083601f840112614e6957600080fd5b50813567ffffffffffffffff811115614e8157600080fd5b6020830191508360208260051b8501011115614df457600080fd5b60008060008060008060008060e0898b031215614eb857600080fd5b606089018a811115614ec957600080fd5b8998503567ffffffffffffffff80821115614ee357600080fd5b614eef8c838d01614db2565b909950975060808b0135915080821115614f0857600080fd5b614f148c838d01614e57565b909750955060a08b0135915080821115614f2d57600080fd5b50614f3a8b828c01614e57565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c08789031215614f6c57600080fd5b863567ffffffffffffffff80821115614f8457600080fd5b614f908a838b0161484d565b97506020890135915080821115614fa657600080fd5b614fb28a838b0161484d565b9650614fc060408a016148d0565b95506060890135915080821115614fd657600080fd5b614fe28a838b01614a9c565b9450614ff060808a01614a84565b935060a089013591508082111561500657600080fd5b5061501389828a01614a9c565b9150509295509295509295565b60006020828403121561503257600080fd5b813561503d8161481b565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160290811690818114613a8657613a86615044565b6000602082840312156150a157600080fd5b5051919050565b63ffffffff818116838216019080821115613a8657613a86615044565b600081518084526020808501945080840160005b8381101561510b57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016150d9565b509495945050505050565b6020815261512d60208201835163ffffffff169052565b60006020830151615146604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006151c58185018363ffffffff169052565b84015190506101206151ee8482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015190506101406152058482018361ffff169052565b840151905061016061522e8482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e0808601829052919250906152766102208601846150c5565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036152fc576152fc615044565b5060010190565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153338184018a6150c5565b9050828103608084015261534781896150c5565b905060ff871660a084015282810360c08401526153648187614d3b565b905067ffffffffffffffff851660e08401528281036101008401526153898185614d3b565b9c9b505050505050505050505050565b6000602082840312156153ab57600080fd5b5035919050565b6bffffffffffffffffffffffff818116838216019080821115613a8657613a86615044565b8082018082111561222f5761222f615044565b60ff818116838216019081111561222f5761222f615044565b8051614848816148db565b80516148488161481b565b8051614848816148f8565b805161484881614911565b80516148488161492d565b600082601f83011261544b57600080fd5b8151602061545b61486e836147f7565b82815260059290921b8401810191818101908684111561547a57600080fd5b8286015b848110156148b65780516154918161481b565b835291830191830161547e565b600082601f8301126154af57600080fd5b815160206154bf61486e836147f7565b82815260059290921b840181019181810190868411156154de57600080fd5b8286015b848110156148b65780516154f58161481b565b83529183019183016154e2565b600082601f83011261551357600080fd5b8151602061552361486e836147f7565b82815260c0928302850182019282820191908785111561554257600080fd5b8387015b85811015614c165781818a03121561555e5760008081fd5b615566614785565b8151615571816148db565b81528186015161558081614911565b818701526040828101516155938161481b565b908201526060828101516155a6816148c1565b908201526080828101519082015260a0808301516155c381614b2a565b908201528452928401928101615546565b6000806000606084860312156155e957600080fd5b835167ffffffffffffffff8082111561560157600080fd5b90850190610200828803121561561657600080fd5b61561e61475b565b61562783615403565b815261563560208401615403565b602082015261564660408401615403565b60408201526156576060840161540e565b606082015261566860808401615419565b608082015261567960a08401615424565b60a082015261568a60c08401615403565b60c082015261569b60e08401615403565b60e08201526101006156ae81850161540e565b908201526101206156c084820161542f565b908201526101406156d284820161540e565b90820152610160838101519082015261018080840151908201526101a080840151908201526101c0808401518381111561570b57600080fd5b6157178a82870161543a565b8284015250506101e061572b81850161540e565b90820152602087015190955091508082111561574657600080fd5b6157528783880161549e565b9350604086015191508082111561576857600080fd5b5061577586828701615502565b9150509250925092565b60006020828403121561579157600080fd5b815161503d816148c1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526158128285018b6150c5565b91508382036080850152615826828a6150c5565b915060ff881660a085015283820360c08501526158438288614d3b565b90861660e085015283810361010085015290506153898185614d3b565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f83011261589757600080fd5b813560206158a761486e836147f7565b82815260059290921b840181019181810190868411156158c657600080fd5b8286015b848110156148b657803583529183019183016158ca565b600082601f8301126158f257600080fd5b8135602061590261486e836147f7565b82815260059290921b8401810191818101908684111561592157600080fd5b8286015b848110156148b657803567ffffffffffffffff8111156159455760008081fd5b6159538986838b0101614a9c565b845250918301918301615925565b60006020828403121561597357600080fd5b813567ffffffffffffffff8082111561598b57600080fd5b9083019060c0828603121561599f57600080fd5b6159a7614785565b82358152602083013560208201526040830135828111156159c757600080fd5b6159d387828601615886565b6040830152506060830135828111156159eb57600080fd5b6159f787828601615886565b606083015250608083013582811115615a0f57600080fd5b615a1b878286016158e1565b60808301525060a083013582811115615a3357600080fd5b615a3f878286016158e1565b60a08301525095945050505050565b61ffff818116838216019080821115613a8657613a86615044565b808202811582820484141761222f5761222f615044565b8181038181111561222f5761222f615044565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ad157615ad1615a93565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000615b096080830184614d3b565b9695505050505050565b6bffffffffffffffffffffffff828116828216039080821115613a8657613a86615044565b60006bffffffffffffffffffffffff80841680615b5757615b57615a93565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114615b8b57615b8b615044565b505092915050565b8281526040602082015260006135556040830184614d3b565b60008060408385031215615bbf57600080fd5b8251615bca816148f8565b6020939093015192949293505050565b805169ffffffffffffffffffff8116811461484857600080fd5b600080600080600060a08688031215615c0c57600080fd5b615c1586615bda565b9450602086015193506040860151925060608601519150615c3860808701615bda565b90509295509295909350565b6fffffffffffffffffffffffffffffffff818116838216019080821115613a8657613a86615044565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215615cae57600080fd5b6040516040810181811067ffffffffffffffff82111715615cd157615cd161472c565b6040528251615cdf816148db565b81526020928301519281019290925250919050565b600060a08284031215615d0657600080fd5b60405160a0810181811067ffffffffffffffff82111715615d2957615d2961472c565b806040525082518152602083015160208201526040830151615d4a816148db565b60408201526060830151615d5d816148db565b60608201526080928301519281019290925250919050565b600181815b80851115615dce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615db457615db4615044565b80851615615dc157918102915b93841c9390800290615d7a565b509250929050565b600082615de55750600161222f565b81615df25750600061222f565b8160018114615e085760028114615e1257615e2e565b600191505061222f565b60ff841115615e2357615e23615044565b50506001821b61222f565b5060208310610133831016604e8410600b8410161715615e51575081810a61222f565b615e5b8383615d75565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615e8d57615e8d615044565b029392505050565b600061222c8383615dd656fea164736f6c6343000813000a",
}
var AutomationRegistryABI = AutomationRegistryMetaData.ABI
@@ -343,18 +344,6 @@ func (_AutomationRegistry *AutomationRegistryTransactorSession) AcceptOwnership(
return _AutomationRegistry.Contract.AcceptOwnership(&_AutomationRegistry.TransactOpts)
}
-func (_AutomationRegistry *AutomationRegistryTransactor) AddFunds(opts *bind.TransactOpts, id *big.Int, amount *big.Int) (*types.Transaction, error) {
- return _AutomationRegistry.contract.Transact(opts, "addFunds", id, amount)
-}
-
-func (_AutomationRegistry *AutomationRegistrySession) AddFunds(id *big.Int, amount *big.Int) (*types.Transaction, error) {
- return _AutomationRegistry.Contract.AddFunds(&_AutomationRegistry.TransactOpts, id, amount)
-}
-
-func (_AutomationRegistry *AutomationRegistryTransactorSession) AddFunds(id *big.Int, amount *big.Int) (*types.Transaction, error) {
- return _AutomationRegistry.Contract.AddFunds(&_AutomationRegistry.TransactOpts, id, amount)
-}
-
func (_AutomationRegistry *AutomationRegistryTransactor) OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
return _AutomationRegistry.contract.Transact(opts, "onTokenTransfer", sender, amount, data)
}
@@ -5473,7 +5462,7 @@ func (AutomationRegistryBillingConfigOverrideRemoved) Topic() common.Hash {
}
func (AutomationRegistryBillingConfigSet) Topic() common.Hash {
- return common.HexToHash("0x720a5849025dc4fd0061aed1bb30efd713cde64ce7f8d807953ecca27c8f143c")
+ return common.HexToHash("0xca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba3")
}
func (AutomationRegistryCancelledUpkeepReport) Topic() common.Hash {
@@ -5633,8 +5622,6 @@ type AutomationRegistryInterface interface {
AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
- AddFunds(opts *bind.TransactOpts, id *big.Int, amount *big.Int) (*types.Transaction, error)
-
OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error)
SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error)
diff --git a/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go b/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go
index 7ff232e0239..a72ff506c90 100644
--- a/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go
+++ b/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go
@@ -34,6 +34,7 @@ type AutomationRegistryBase23BillingConfig struct {
GasFeePPB uint32
FlatFeeMilliCents *big.Int
PriceFeed common.Address
+ Decimals uint8
FallbackPrice *big.Int
MinSpend *big.Int
}
@@ -133,7 +134,7 @@ type IAutomationV21PlusCommonUpkeepInfoLegacy struct {
}
var IAutomationRegistryMaster23MetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disableOffchainPayments\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getBillingToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getBillingTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBillingTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFallbackNativePrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getHotVars\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyGuard\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.HotVars\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNativeUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumUpkeeps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPayoutMode\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getReserveAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structIAutomationV21PlusCommon.StateLegacy\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structIAutomationV21PlusCommon.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistryBase2_3.Storage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structIAutomationV21PlusCommon.UpkeepInfoLegacy\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNativeTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"removeBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"billingOverrides\",\"type\":\"tuple\"}],\"name\":\"setBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"address[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settleNOPsOffchain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"supportsBillingToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20Fees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disableOffchainPayments\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getBillingToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getBillingTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBillingTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFallbackNativePrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getHotVars\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyGuard\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.HotVars\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNativeUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumUpkeeps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPayoutMode\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getReserveAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structIAutomationV21PlusCommon.StateLegacy\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structIAutomationV21PlusCommon.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistryBase2_3.Storage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structIAutomationV21PlusCommon.UpkeepInfoLegacy\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNativeTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"removeBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"billingOverrides\",\"type\":\"tuple\"}],\"name\":\"setBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"address[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settleNOPsOffchain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"supportsBillingToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20Fees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
}
var IAutomationRegistryMaster23ABI = IAutomationRegistryMaster23MetaData.ABI
@@ -7070,7 +7071,7 @@ func (IAutomationRegistryMaster23BillingConfigOverrideRemoved) Topic() common.Ha
}
func (IAutomationRegistryMaster23BillingConfigSet) Topic() common.Hash {
- return common.HexToHash("0x720a5849025dc4fd0061aed1bb30efd713cde64ce7f8d807953ecca27c8f143c")
+ return common.HexToHash("0xca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba3")
}
func (IAutomationRegistryMaster23CancelledUpkeepReport) Topic() common.Hash {
diff --git a/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus/vrf_malicious_consumer_v2_plus.go b/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus/vrf_malicious_consumer_v2_plus.go
index 50df8e4312c..10606a11b79 100644
--- a/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus/vrf_malicious_consumer_v2_plus.go
+++ b/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus/vrf_malicious_consumer_v2_plus.go
@@ -32,7 +32,7 @@ var (
var VRFMaliciousConsumerV2PlusMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorSet\",\"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\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"createSubscriptionAndFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"requestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60806040523480156200001157600080fd5b5060405162001291380380620012918339810160408190526200003491620001e8565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000120565b5050506001600160a01b038116620000ea5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039283166001600160a01b031991821617909155600580549390921692169190911790555062000220565b336001600160a01b038216036200017a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001e357600080fd5b919050565b60008060408385031215620001fc57600080fd5b6200020783620001cb565b91506200021760208401620001cb565b90509250929050565b61106180620002306000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80639eccacf611610081578063f08c5daa1161005b578063f08c5daa146101bd578063f2fde38b146101c6578063f6eaffc8146101d957600080fd5b80639eccacf614610181578063cf62c8ab146101a1578063e89e106a146101b457600080fd5b806379ba5097116100b257806379ba5097146101275780638da5cb5b1461012f5780638ea981171461016e57600080fd5b80631fe543e3146100d957806336bfffed146100ee5780635e3b709f14610101575b600080fd5b6100ec6100e7366004610cb1565b6101ec565b005b6100ec6100fc366004610d7c565b610272565b61011461010f366004610e14565b6103ad565b6040519081526020015b60405180910390f35b6100ec610494565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011e565b6100ec61017c366004610e2d565b610591565b6002546101499073ffffffffffffffffffffffffffffffffffffffff1681565b6100ec6101af366004610e48565b61071b565b61011460045481565b61011460065481565b6100ec6101d4366004610e2d565b610906565b6101146101e7366004610e14565b61091a565b60025473ffffffffffffffffffffffffffffffffffffffff163314610264576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61026e828261093b565b5050565b6007546000036102de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161025b565b60005b815181101561026e57600254600754835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061032457610324610e76565b60200260200101516040518363ffffffff1660e01b815260040161036892919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561038257600080fd5b505af1158015610396573d6000803e3d6000fd5b5050505080806103a590610ea5565b9150506102e1565b60088190556040805160c08101825282815260075460208083019190915260018284018190526207a1206060840152608083015282519081018352600080825260a083019190915260025492517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff1690639b1c385e9061044a908490600401610f68565b6020604051808303816000875af1158015610469573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048d9190610fcd565b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610515576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161025b565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906105d1575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561065557336105f660005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161025b565b73ffffffffffffffffffffffffffffffffffffffff81166106a2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b60075460000361084757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b89190610fcd565b60078190556002546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b15801561082e57600080fd5b505af1158015610842573d6000803e3d6000fd5b505050505b6005546002546007546040805160208082019390935281518082039093018352808201918290527f4000aea00000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0936108c393911691869190604401610fe6565b6020604051808303816000875af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026e9190611032565b61090e610a37565b61091781610aba565b50565b6003818154811061092a57600080fd5b600091825260209091200154905081565b5a6006558051610952906003906020840190610baf565b5060048281556040805160c0810182526008548152600754602080830191909152600182840181905262030d4060608401526080830152825190810183526000815260a082015260025491517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff90921691639b1c385e916109ee91859101610f68565b6020604051808303816000875af1158015610a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a319190610fcd565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ab8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161025b565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161025b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610bea579160200282015b82811115610bea578251825591602001919060010190610bcf565b50610bf6929150610bfa565b5090565b5b80821115610bf65760008155600101610bfb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c8557610c85610c0f565b604052919050565b600067ffffffffffffffff821115610ca757610ca7610c0f565b5060051b60200190565b60008060408385031215610cc457600080fd5b8235915060208084013567ffffffffffffffff811115610ce357600080fd5b8401601f81018613610cf457600080fd5b8035610d07610d0282610c8d565b610c3e565b81815260059190911b82018301908381019088831115610d2657600080fd5b928401925b82841015610d4457833582529284019290840190610d2b565b80955050505050509250929050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610d7757600080fd5b919050565b60006020808385031215610d8f57600080fd5b823567ffffffffffffffff811115610da657600080fd5b8301601f81018513610db757600080fd5b8035610dc5610d0282610c8d565b81815260059190911b82018301908381019087831115610de457600080fd5b928401925b82841015610e0957610dfa84610d53565b82529284019290840190610de9565b979650505050505050565b600060208284031215610e2657600080fd5b5035919050565b600060208284031215610e3f57600080fd5b61048d82610d53565b600060208284031215610e5a57600080fd5b81356bffffffffffffffffffffffff8116811461048d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b6000815180845260005b81811015610f2a57602081850181015186830182015201610f0e565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610fc560e0840182610f04565b949350505050565b600060208284031215610fdf57600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006110296060830184610f04565b95945050505050565b60006020828403121561104457600080fd5b8151801515811461048d57600080fdfea164736f6c6343000813000a",
+ Bin: "0x60806040523480156200001157600080fd5b5060405162001246380380620012468339810160408190526200003491620001e8565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000120565b5050506001600160a01b038116620000ea5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039283166001600160a01b031991821617909155600580549390921692169190911790555062000220565b336001600160a01b038216036200017a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001e357600080fd5b919050565b60008060408385031215620001fc57600080fd5b6200020783620001cb565b91506200021760208401620001cb565b90509250929050565b61101680620002306000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80639eccacf611610081578063f08c5daa1161005b578063f08c5daa146101bd578063f2fde38b146101c6578063f6eaffc8146101d957600080fd5b80639eccacf614610181578063cf62c8ab146101a1578063e89e106a146101b457600080fd5b806379ba5097116100b257806379ba5097146101275780638da5cb5b1461012f5780638ea981171461016e57600080fd5b80631fe543e3146100d957806336bfffed146100ee5780635e3b709f14610101575b600080fd5b6100ec6100e7366004610c0f565b6101ec565b005b6100ec6100fc366004610ce6565b610274565b61011461010f366004610dc9565b6103b3565b6040519081526020015b60405180910390f35b6100ec61049a565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011e565b6100ec61017c366004610de2565b610597565b6002546101499073ffffffffffffffffffffffffffffffffffffffff1681565b6100ec6101af366004610dfd565b610721565b61011460045481565b61011460065481565b6100ec6101d4366004610de2565b61090c565b6101146101e7366004610dc9565b610920565b60025473ffffffffffffffffffffffffffffffffffffffff163314610264576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61026f838383610941565b505050565b6007546000036102e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161025b565b60005b81518110156103af57600254600754835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061032657610326610e2b565b60200260200101516040518363ffffffff1660e01b815260040161036a92919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561038457600080fd5b505af1158015610398573d6000803e3d6000fd5b5050505080806103a790610e5a565b9150506102e3565b5050565b60088190556040805160c08101825282815260075460208083019190915260018284018190526207a1206060840152608083015282519081018352600080825260a083019190915260025492517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610450908490600401610f1d565b6020604051808303816000875af115801561046f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104939190610f82565b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461051b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161025b565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906105d7575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561065b57336105fc60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161025b565b73ffffffffffffffffffffffffffffffffffffffff81166106a8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b60075460000361084d57600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af115801561079a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107be9190610f82565b60078190556002546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b15801561083457600080fd5b505af1158015610848573d6000803e3d6000fd5b505050505b6005546002546007546040805160208082019390935281518082039093018352808201918290527f4000aea00000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0936108c993911691869190604401610f9b565b6020604051808303816000875af11580156108e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103af9190610fe7565b610914610a37565b61091d81610aba565b50565b6003818154811061093057600080fd5b600091825260209091200154905081565b5a60065561095160038383610baf565b5060048381556040805160c0810182526008548152600754602080830191909152600182840181905262030d4060608401526080830152825190810183526000815260a082015260025491517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff90921691639b1c385e916109ed91859101610f1d565b6020604051808303816000875af1158015610a0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a309190610f82565b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ab8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161025b565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610b39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161025b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610bea579160200282015b82811115610bea578235825591602001919060010190610bcf565b50610bf6929150610bfa565b5090565b5b80821115610bf65760008155600101610bfb565b600080600060408486031215610c2457600080fd5b83359250602084013567ffffffffffffffff80821115610c4357600080fd5b818601915086601f830112610c5757600080fd5b813581811115610c6657600080fd5b8760208260051b8501011115610c7b57600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610ce157600080fd5b919050565b60006020808385031215610cf957600080fd5b823567ffffffffffffffff80821115610d1157600080fd5b818501915085601f830112610d2557600080fd5b813581811115610d3757610d37610c8e565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610d7a57610d7a610c8e565b604052918252848201925083810185019188831115610d9857600080fd5b938501935b82851015610dbd57610dae85610cbd565b84529385019392850192610d9d565b98975050505050505050565b600060208284031215610ddb57600080fd5b5035919050565b600060208284031215610df457600080fd5b61049382610cbd565b600060208284031215610e0f57600080fd5b81356bffffffffffffffffffffffff8116811461049357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610eb2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b6000815180845260005b81811015610edf57602081850181015186830182015201610ec3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610f7a60e0840182610eb9565b949350505050565b600060208284031215610f9457600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000610fde6060830184610eb9565b95945050505050565b600060208284031215610ff957600080fd5b8151801515811461049357600080fdfea164736f6c6343000813000a",
}
var VRFMaliciousConsumerV2PlusABI = VRFMaliciousConsumerV2PlusMetaData.ABI
diff --git a/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go b/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go
index 46c83dc304f..222bc627f2c 100644
--- a/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go
+++ b/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go
@@ -32,7 +32,7 @@ var (
var VRFV2PlusLoadTestWithMetricsMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorSet\",\"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\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"getRequestBlockTimes\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"_nativePayment\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageResponseTimeInBlocksMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageResponseTimeInSecondsMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestResponseTimeInBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestResponseTimeInSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestBlockTimes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_responseCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestResponseTimeInBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestResponseTimeInSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x6080604052600060055560006006556103e760075560006008556103e76009556000600a553480156200003157600080fd5b506040516200176f3803806200176f8339810160408190526200005491620001dc565b803380600081620000ac5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000df57620000df8162000131565b5050506001600160a01b0381166200010a5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055506200020e565b336001600160a01b038216036200018b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a3565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001ef57600080fd5b81516001600160a01b03811681146200020757600080fd5b9392505050565b611551806200021e6000396000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638ea98117116100d8578063ad00fe611161008c578063d8a4676f11610066578063d8a4676f14610334578063dc1670db14610359578063f2fde38b1461036257600080fd5b8063ad00fe611461031a578063b1e2174914610323578063d826f88f1461032c57600080fd5b80639eccacf6116100bd5780639eccacf614610286578063a168fa89146102a6578063a4c52cf51461031157600080fd5b80638ea981171461024b578063958cccb71461025e57600080fd5b8063557d2e921161012f57806379ba50971161011457806379ba5097146101fb57806381a4342c146102035780638da5cb5b1461020c57600080fd5b8063557d2e92146101df5780636846de20146101e857600080fd5b80631742748e116101605780631742748e146101b85780631fe543e3146101c157806339aea80a146101d657600080fd5b806301e5f8281461017c5780630b26348614610198575b600080fd5b61018560065481565b6040519081526020015b60405180910390f35b6101ab6101a6366004611053565b610375565b60405161018f9190611075565b610185600a5481565b6101d46101cf3660046110ee565b610473565b005b61018560075481565b61018560045481565b6101d46101f6366004611201565b6104f9565b6101d461070a565b61018560055481565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018f565b6101d4610259366004611280565b610807565b61027161026c3660046112bd565b610991565b60405163ffffffff909116815260200161018f565b6002546102269073ffffffffffffffffffffffffffffffffffffffff1681565b6102e76102b43660046112bd565b600d602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a00161018f565b61018560095481565b61018560085481565b610185600b5481565b6101d46109cb565b6103476103423660046112bd565b610a04565b60405161018f969594939291906112d6565b61018560035481565b6101d4610370366004611280565b610ae9565b606060006103838385611371565b600c549091508111156103955750600c545b60006103a18583611384565b67ffffffffffffffff8111156103b9576103b96110bf565b6040519080825280602002602001820160405280156103e2578160200160208202803683370190505b509050845b8281101561046857600c818154811061040257610402611397565b6000918252602090912060088204015460079091166004026101000a900463ffffffff16826104318884611384565b8151811061044157610441611397565b63ffffffff9092166020928302919091019091015280610460816113c6565b9150506103e7565b509150505b92915050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146104eb576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6104f58282610afd565b5050565b610501610c74565b60005b8161ffff168161ffff1610156107005760006040518060c001604052808881526020018a81526020018961ffff1681526020018763ffffffff1681526020018563ffffffff1681526020016105686040518060200160405280891515815250610cf5565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e906105c69085906004016113fe565b6020604051808303816000875af11580156105e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060991906114b8565b600b8190559050600061061a610db1565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600d815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690151517815590518051949550919390926106a8926001850192910190610fd2565b506040820151600282015560608201516003820155608082015160048083019190915560a09092015160059091015580549060006106e5836113c6565b919050555050505080806106f8906114d1565b915050610504565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461078b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104e2565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610847575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156108cb573361086c60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016104e2565b73ffffffffffffffffffffffffffffffffffffffff8116610918576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b600c81815481106109a157600080fd5b9060005260206000209060089182820401919006600402915054906101000a900463ffffffff1681565b6000600581905560068190556103e76007819055600a829055600882905560095560048190556003819055610a0290600c9061101d565b565b6000818152600d60209081526040808320815160c081018352815460ff1615158152600182018054845181870281018701909552808552606095879586958695869586959194929385840193909290830182828015610a8257602002820191906000526020600020905b815481526020019060010190808311610a6e575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b610af1610c74565b610afa81610e3f565b50565b6000828152600d6020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558351610b4c939290910191840190610fd2565b506000828152600d6020526040902042600390910155610b6a610db1565b6000838152600d6020526040812060058101839055600401549091610b8f9190611384565b6000848152600d6020526040812060028101546003909101549293509091610bb79190611384565b9050610bce82600754600654600554600354610f34565b600555600755600655600954600854600a54600354610bf293859390929091610f34565b600a5560095560085560038054906000610c0b836113c6565b9091555050600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c76008820401805460079092166004026101000a63ffffffff81810219909316949092169190910292909217909155505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104e2565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610d2e91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b600046610dbd81610faf565b15610e3857606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3291906114b8565b91505090565b4391505090565b3373ffffffffffffffffffffffffffffffffffffffff821603610ebe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104e2565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808080610f4689620f42406114f2565b905086891115610f54578896505b878910610f615787610f63565b885b97506000808611610f745781610f9e565b610f7f866001611371565b82610f8a888a6114f2565b610f949190611371565b610f9e9190611509565b979a98995096979650505050505050565b600061a4b1821480610fc3575062066eed82145b8061046d57505062066eee1490565b82805482825590600052602060002090810192821561100d579160200282015b8281111561100d578251825591602001919060010190610ff2565b5061101992915061103e565b5090565b508054600082556007016008900490600052602060002090810190610afa91905b5b80821115611019576000815560010161103f565b6000806040838503121561106657600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156110b357835163ffffffff1683529284019291840191600101611091565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561110157600080fd5b8235915060208084013567ffffffffffffffff8082111561112157600080fd5b818601915086601f83011261113557600080fd5b813581811115611147576111476110bf565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561118a5761118a6110bf565b6040529182528482019250838101850191898311156111a857600080fd5b938501935b828510156111c6578435845293850193928501926111ad565b8096505050505050509250929050565b803561ffff811681146111e857600080fd5b919050565b803563ffffffff811681146111e857600080fd5b600080600080600080600060e0888a03121561121c57600080fd5b8735965061122c602089016111d6565b955060408801359450611241606089016111ed565b93506080880135801515811461125657600080fd5b925061126460a089016111ed565b915061127260c089016111d6565b905092959891949750929550565b60006020828403121561129257600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146112b657600080fd5b9392505050565b6000602082840312156112cf57600080fd5b5035919050565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015611319578451835293830193918301916001016112fd565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561046d5761046d611342565b8181038181111561046d5761046d611342565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113f7576113f7611342565b5060010190565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b818110156114755782810184015186820161010001528301611458565b5061010092506000838287010152827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116860101935050505092915050565b6000602082840312156114ca57600080fd5b5051919050565b600061ffff8083168181036114e8576114e8611342565b6001019392505050565b808202811582820484141761046d5761046d611342565b60008261153f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000813000a",
+ Bin: "0x6080604052600060055560006006556103e760075560006008556103e76009556000600a553480156200003157600080fd5b506040516200173e3803806200173e8339810160408190526200005491620001dc565b803380600081620000ac5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000df57620000df8162000131565b5050506001600160a01b0381166200010a5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055506200020e565b336001600160a01b038216036200018b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a3565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001ef57600080fd5b81516001600160a01b03811681146200020757600080fd5b9392505050565b611520806200021e6000396000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638ea98117116100d8578063ad00fe611161008c578063d8a4676f11610066578063d8a4676f14610334578063dc1670db14610359578063f2fde38b1461036257600080fd5b8063ad00fe611461031a578063b1e2174914610323578063d826f88f1461032c57600080fd5b80639eccacf6116100bd5780639eccacf614610286578063a168fa89146102a6578063a4c52cf51461031157600080fd5b80638ea981171461024b578063958cccb71461025e57600080fd5b8063557d2e921161012f57806379ba50971161011457806379ba5097146101fb57806381a4342c146102035780638da5cb5b1461020c57600080fd5b8063557d2e92146101df5780636846de20146101e857600080fd5b80631742748e116101605780631742748e146101b85780631fe543e3146101c157806339aea80a146101d657600080fd5b806301e5f8281461017c5780630b26348614610198575b600080fd5b61018560065481565b6040519081526020015b60405180910390f35b6101ab6101a636600461108b565b610375565b60405161018f91906110ad565b610185600a5481565b6101d46101cf3660046110f7565b610473565b005b61018560075481565b61018560045481565b6101d46101f63660046111a1565b6104fb565b6101d461070c565b61018560055481565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018f565b6101d4610259366004611220565b610809565b61027161026c36600461125d565b610993565b60405163ffffffff909116815260200161018f565b6002546102269073ffffffffffffffffffffffffffffffffffffffff1681565b6102e76102b436600461125d565b600d602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a00161018f565b61018560095481565b61018560085481565b610185600b5481565b6101d46109cd565b61034761034236600461125d565b610a06565b60405161018f96959493929190611276565b61018560035481565b6101d4610370366004611220565b610aeb565b606060006103838385611311565b600c549091508111156103955750600c545b60006103a18583611324565b67ffffffffffffffff8111156103b9576103b9611337565b6040519080825280602002602001820160405280156103e2578160200160208202803683370190505b509050845b8281101561046857600c818154811061040257610402611366565b6000918252602090912060088204015460079091166004026101000a900463ffffffff16826104318884611324565b8151811061044157610441611366565b63ffffffff909216602092830291909101909101528061046081611395565b9150506103e7565b509150505b92915050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146104eb576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6104f6838383610aff565b505050565b610503610c6d565b60005b8161ffff168161ffff1610156107025760006040518060c001604052808881526020018a81526020018961ffff1681526020018763ffffffff1681526020018563ffffffff16815260200161056a6040518060200160405280891515815250610cee565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e906105c89085906004016113cd565b6020604051808303816000875af11580156105e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060b9190611487565b600b8190559050600061061c610daa565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600d815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690151517815590518051949550919390926106aa926001850192910190610fcb565b506040820151600282015560608201516003820155608082015160048083019190915560a09092015160059091015580549060006106e783611395565b919050555050505080806106fa906114a0565b915050610506565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461078d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104e2565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610849575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156108cd573361086e60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016104e2565b73ffffffffffffffffffffffffffffffffffffffff811661091a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b600c81815481106109a357600080fd5b9060005260206000209060089182820401919006600402915054906101000a900463ffffffff1681565b6000600581905560068190556103e76007819055600a829055600882905560095560048190556003819055610a0490600c90611016565b565b6000818152600d60209081526040808320815160c081018352815460ff1615158152600182018054845181870281018701909552808552606095879586958695869586959194929385840193909290830182828015610a8457602002820191906000526020600020905b815481526020019060010190808311610a70575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b610af3610c6d565b610afc81610e38565b50565b6000838152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081178255610b449101838361103b565b506000838152600d6020526040902042600390910155610b62610daa565b6000848152600d6020526040812060058101839055600401549091610b879190611324565b6000858152600d6020526040812060028101546003909101549293509091610baf9190611324565b9050610bc682600754600654600554600354610f2d565b600555600755600655600954600854600a54600354610bea93859390929091610f2d565b600a5560095560085560038054906000610c0383611395565b9091555050600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c76008820401805460079092166004026101000a63ffffffff8181021990931694909216919091029290921790915550505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104e2565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610d2791511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b600046610db681610fa8565b15610e3157606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2b9190611487565b91505090565b4391505090565b3373ffffffffffffffffffffffffffffffffffffffff821603610eb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104e2565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808080610f3f89620f42406114c1565b905086891115610f4d578896505b878910610f5a5787610f5c565b885b97506000808611610f6d5781610f97565b610f78866001611311565b82610f83888a6114c1565b610f8d9190611311565b610f9791906114d8565b979a98995096979650505050505050565b600061a4b1821480610fbc575062066eed82145b8061046d57505062066eee1490565b828054828255906000526020600020908101928215611006579160200282015b82811115611006578251825591602001919060010190610feb565b50611012929150611076565b5090565b508054600082556007016008900490600052602060002090810190610afc9190611076565b828054828255906000526020600020908101928215611006579160200282015b8281111561100657823582559160200191906001019061105b565b5b808211156110125760008155600101611077565b6000806040838503121561109e57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156110eb57835163ffffffff16835292840192918401916001016110c9565b50909695505050505050565b60008060006040848603121561110c57600080fd5b83359250602084013567ffffffffffffffff8082111561112b57600080fd5b818601915086601f83011261113f57600080fd5b81358181111561114e57600080fd5b8760208260051b850101111561116357600080fd5b6020830194508093505050509250925092565b803561ffff8116811461118857600080fd5b919050565b803563ffffffff8116811461118857600080fd5b600080600080600080600060e0888a0312156111bc57600080fd5b873596506111cc60208901611176565b9550604088013594506111e16060890161118d565b9350608088013580151581146111f657600080fd5b925061120460a0890161118d565b915061121260c08901611176565b905092959891949750929550565b60006020828403121561123257600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461125657600080fd5b9392505050565b60006020828403121561126f57600080fd5b5035919050565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b818110156112b95784518352938301939183019160010161129d565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561046d5761046d6112e2565b8181038181111561046d5761046d6112e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113c6576113c66112e2565b5060010190565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b818110156114445782810184015186820161010001528301611427565b5061010092506000838287010152827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116860101935050505092915050565b60006020828403121561149957600080fd5b5051919050565b600061ffff8083168181036114b7576114b76112e2565b6001019392505050565b808202811582820484141761046d5761046d6112e2565b60008261150e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000813000a",
}
var VRFV2PlusLoadTestWithMetricsABI = VRFV2PlusLoadTestWithMetricsMetaData.ABI
diff --git a/core/gethwrappers/generated/vrf_v2plus_single_consumer/vrf_v2plus_single_consumer.go b/core/gethwrappers/generated/vrf_v2plus_single_consumer/vrf_v2plus_single_consumer.go
index 583b647c8b4..ab4511e233b 100644
--- a/core/gethwrappers/generated/vrf_v2plus_single_consumer/vrf_v2plus_single_consumer.go
+++ b/core/gethwrappers/generated/vrf_v2plus_single_consumer/vrf_v2plus_single_consumer.go
@@ -32,7 +32,7 @@ var (
var VRFV2PlusSingleConsumerExampleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorSet\",\"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\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"fundAndRequestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestConfig\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"subscribe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"unsubscribe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60806040523480156200001157600080fd5b506040516200187f3803806200187f83398101604081905262000034916200046f565b8633806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001d0565b5050506001600160a01b038116620000ea5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b03199081166001600160a01b039384161790915560038054821692891692909217909155600a80543392169190911790556040805160c081018252600080825263ffffffff8881166020840181905261ffff8916948401859052908716606084018190526080840187905285151560a09094018490526004929092556005805465ffffffffffff19169091176401000000009094029390931763ffffffff60301b191666010000000000009091021790915560068390556007805460ff19169091179055620001c36200027b565b505050505050506200053b565b336001600160a01b038216036200022a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b62000285620003df565b604080516001808252818301909252600091602080830190803683370190505090503081600081518110620002be57620002be6200050b565b6001600160a01b039283166020918202929092018101919091526002546040805163288688f960e21b81529051919093169263a21a23e492600480830193919282900301816000875af11580156200031a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000340919062000521565b600481905560025482516001600160a01b039091169163bec4c08c9184906000906200037057620003706200050b565b60200260200101516040518363ffffffff1660e01b8152600401620003a89291909182526001600160a01b0316602082015260400190565b600060405180830381600087803b158015620003c357600080fd5b505af1158015620003d8573d6000803e3d6000fd5b5050505050565b6000546001600160a01b031633146200043b5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000083565b565b80516001600160a01b03811681146200045557600080fd5b919050565b805163ffffffff811681146200045557600080fd5b600080600080600080600060e0888a0312156200048b57600080fd5b62000496886200043d565b9650620004a6602089016200043d565b9550620004b6604089016200045a565b9450606088015161ffff81168114620004ce57600080fd5b9350620004de608089016200045a565b925060a0880151915060c08801518015158114620004fb57600080fd5b8091505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200053457600080fd5b5051919050565b611334806200054b6000396000f3fe608060405234801561001057600080fd5b50600436106100f45760003560e01c80638da5cb5b11610097578063e0c8628911610066578063e0c862891461025c578063e89e106a14610264578063f2fde38b1461027b578063f6eaffc81461028e57600080fd5b80638da5cb5b146101e25780638ea98117146102215780638f449a05146102345780639eccacf61461023c57600080fd5b80637262561c116100d35780637262561c1461013457806379ba5097146101475780637db9263f1461014f57806386850e93146101cf57600080fd5b8062f714ce146100f95780631fe543e31461010e5780636fd700bb14610121575b600080fd5b61010c610107366004611038565b6102a1565b005b61010c61011c366004611093565b61034b565b61010c61012f36600461117b565b6103d1565b61010c610142366004611194565b6105e9565b61010c610686565b60045460055460065460075461018b939263ffffffff8082169361ffff6401000000008404169366010000000000009093049091169160ff1686565b6040805196875263ffffffff958616602088015261ffff90941693860193909352921660608401526080830191909152151560a082015260c0015b60405180910390f35b61010c6101dd36600461117b565b610783565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b61010c61022f366004611194565b61084a565b61010c6109d4565b6002546101fc9073ffffffffffffffffffffffffffffffffffffffff1681565b61010c610b6a565b61026d60095481565b6040519081526020016101c6565b61010c610289366004611194565b610cc8565b61026d61029c36600461117b565b610cdc565b6102a9610cfd565b6003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018590529091169063a9059cbb906044016020604051808303816000875af1158015610322573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034691906111b6565b505050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146103c3576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6103cd8282610d80565b5050565b6103d9610cfd565b6040805160c08101825260045480825260055463ffffffff808216602080860191909152640100000000830461ffff16858701526601000000000000909204166060840152600654608084015260075460ff16151560a0840152600354600254855192830193909352929373ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918691016040516020818303038152906040526040518463ffffffff1660e01b81526004016104959392919061123c565b6020604051808303816000875af11580156104b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d891906111b6565b5060006040518060c001604052808360800151815260200183600001518152602001836040015161ffff168152602001836020015163ffffffff168152602001836060015163ffffffff16815260200161054560405180602001604052808660a001511515815250610dfe565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e9061059e90849060040161127a565b6020604051808303816000875af11580156105bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e191906112df565b600955505050565b6105f1610cfd565b600254600480546040517f0ae095400000000000000000000000000000000000000000000000000000000081529182015273ffffffffffffffffffffffffffffffffffffffff838116602483015290911690630ae0954090604401600060405180830381600087803b15801561066657600080fd5b505af115801561067a573d6000803e3d6000fd5b50506000600455505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610707576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103ba565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61078b610cfd565b6003546002546004546040805160208082019390935281518082039093018352808201918290527f4000aea00000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0936108079391169186919060440161123c565b6020604051808303816000875af1158015610826573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103cd91906111b6565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061088a575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561090e57336108af60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016103ba565b73ffffffffffffffffffffffffffffffffffffffff811661095b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b6109dc610cfd565b604080516001808252818301909252600091602080830190803683370190505090503081600081518110610a1257610a126112f8565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152600254604080517fa21a23e40000000000000000000000000000000000000000000000000000000081529051919093169263a21a23e492600480830193919282900301816000875af1158015610a93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab791906112df565b6004819055600254825173ffffffffffffffffffffffffffffffffffffffff9091169163bec4c08c918490600090610af157610af16112f8565b60200260200101516040518363ffffffff1660e01b8152600401610b3592919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610b4f57600080fd5b505af1158015610b63573d6000803e3d6000fd5b5050505050565b610b72610cfd565b6040805160c08082018352600454825260055463ffffffff808216602080860191825261ffff640100000000850481168789019081526601000000000000909504841660608089019182526006546080808b0191825260075460ff16151560a0808d019182528d519b8c018e5292518b528b518b8801529851909416898c0152945186169088015251909316928501929092528551918201909552905115158152919260009290820190610c2590610dfe565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610c7e90849060040161127a565b6020604051808303816000875af1158015610c9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc191906112df565b6009555050565b610cd0610cfd565b610cd981610eba565b50565b60088181548110610cec57600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103ba565b565b6009548214610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016103ba565b8051610346906008906020840190610faf565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610e3791511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b3373ffffffffffffffffffffffffffffffffffffffff821603610f39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103ba565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610fea579160200282015b82811115610fea578251825591602001919060010190610fcf565b50610ff6929150610ffa565b5090565b5b80821115610ff65760008155600101610ffb565b803573ffffffffffffffffffffffffffffffffffffffff8116811461103357600080fd5b919050565b6000806040838503121561104b57600080fd5b8235915061105b6020840161100f565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156110a657600080fd5b8235915060208084013567ffffffffffffffff808211156110c657600080fd5b818601915086601f8301126110da57600080fd5b8135818111156110ec576110ec611064565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561112f5761112f611064565b60405291825284820192508381018501918983111561114d57600080fd5b938501935b8285101561116b57843584529385019392850192611152565b8096505050505050509250929050565b60006020828403121561118d57600080fd5b5035919050565b6000602082840312156111a657600080fd5b6111af8261100f565b9392505050565b6000602082840312156111c857600080fd5b815180151581146111af57600080fd5b6000815180845260005b818110156111fe576020818501810151868301820152016111e2565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061127160608301846111d8565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c0808401526112d760e08401826111d8565b949350505050565b6000602082840312156112f157600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c6343000813000a",
+ Bin: "0x60806040523480156200001157600080fd5b50604051620017e7380380620017e783398101604081905262000034916200046f565b8633806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001d0565b5050506001600160a01b038116620000ea5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b03199081166001600160a01b039384161790915560038054821692891692909217909155600a80543392169190911790556040805160c081018252600080825263ffffffff8881166020840181905261ffff8916948401859052908716606084018190526080840187905285151560a09094018490526004929092556005805465ffffffffffff19169091176401000000009094029390931763ffffffff60301b191666010000000000009091021790915560068390556007805460ff19169091179055620001c36200027b565b505050505050506200053b565b336001600160a01b038216036200022a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b62000285620003df565b604080516001808252818301909252600091602080830190803683370190505090503081600081518110620002be57620002be6200050b565b6001600160a01b039283166020918202929092018101919091526002546040805163288688f960e21b81529051919093169263a21a23e492600480830193919282900301816000875af11580156200031a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000340919062000521565b600481905560025482516001600160a01b039091169163bec4c08c9184906000906200037057620003706200050b565b60200260200101516040518363ffffffff1660e01b8152600401620003a89291909182526001600160a01b0316602082015260400190565b600060405180830381600087803b158015620003c357600080fd5b505af1158015620003d8573d6000803e3d6000fd5b5050505050565b6000546001600160a01b031633146200043b5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000083565b565b80516001600160a01b03811681146200045557600080fd5b919050565b805163ffffffff811681146200045557600080fd5b600080600080600080600060e0888a0312156200048b57600080fd5b62000496886200043d565b9650620004a6602089016200043d565b9550620004b6604089016200045a565b9450606088015161ffff81168114620004ce57600080fd5b9350620004de608089016200045a565b925060a0880151915060c08801518015158114620004fb57600080fd5b8091505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200053457600080fd5b5051919050565b61129c806200054b6000396000f3fe608060405234801561001057600080fd5b50600436106100f45760003560e01c80638da5cb5b11610097578063e0c8628911610066578063e0c862891461025c578063e89e106a14610264578063f2fde38b1461027b578063f6eaffc81461028e57600080fd5b80638da5cb5b146101e25780638ea98117146102215780638f449a05146102345780639eccacf61461023c57600080fd5b80637262561c116100d35780637262561c1461013457806379ba5097146101475780637db9263f1461014f57806386850e93146101cf57600080fd5b8062f714ce146100f95780631fe543e31461010e5780636fd700bb14610121575b600080fd5b61010c610107366004611038565b6102a1565b005b61010c61011c366004611064565b61034b565b61010c61012f3660046110e3565b6103ce565b61010c6101423660046110fc565b6105e6565b61010c610683565b60045460055460065460075461018b939263ffffffff8082169361ffff6401000000008404169366010000000000009093049091169160ff1686565b6040805196875263ffffffff958616602088015261ffff90941693860193909352921660608401526080830191909152151560a082015260c0015b60405180910390f35b61010c6101dd3660046110e3565b610780565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b61010c61022f3660046110fc565b61084b565b61010c6109d5565b6002546101fc9073ffffffffffffffffffffffffffffffffffffffff1681565b61010c610b6b565b61026d60095481565b6040519081526020016101c6565b61010c6102893660046110fc565b610cc9565b61026d61029c3660046110e3565b610cdd565b6102a9610cfe565b6003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018590529091169063a9059cbb906044016020604051808303816000875af1158015610322573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610346919061111e565b505050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146103c3576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b610346838383610d81565b6103d6610cfe565b6040805160c08101825260045480825260055463ffffffff808216602080860191909152640100000000830461ffff16858701526601000000000000909204166060840152600654608084015260075460ff16151560a0840152600354600254855192830193909352929373ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918691016040516020818303038152906040526040518463ffffffff1660e01b8152600401610492939291906111a4565b6020604051808303816000875af11580156104b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d5919061111e565b5060006040518060c001604052808360800151815260200183600001518152602001836040015161ffff168152602001836020015163ffffffff168152602001836060015163ffffffff16815260200161054260405180602001604052808660a001511515815250610dfe565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e9061059b9084906004016111e2565b6020604051808303816000875af11580156105ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105de9190611247565b600955505050565b6105ee610cfe565b600254600480546040517f0ae095400000000000000000000000000000000000000000000000000000000081529182015273ffffffffffffffffffffffffffffffffffffffff838116602483015290911690630ae0954090604401600060405180830381600087803b15801561066357600080fd5b505af1158015610677573d6000803e3d6000fd5b50506000600455505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610704576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103ba565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610788610cfe565b6003546002546004546040805160208082019390935281518082039093018352808201918290527f4000aea00000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff93841693634000aea093610804939116918691906044016111a4565b6020604051808303816000875af1158015610823573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610847919061111e565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061088b575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561090f57336108b060005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016103ba565b73ffffffffffffffffffffffffffffffffffffffff811661095c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b6109dd610cfe565b604080516001808252818301909252600091602080830190803683370190505090503081600081518110610a1357610a13611260565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152600254604080517fa21a23e40000000000000000000000000000000000000000000000000000000081529051919093169263a21a23e492600480830193919282900301816000875af1158015610a94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab89190611247565b6004819055600254825173ffffffffffffffffffffffffffffffffffffffff9091169163bec4c08c918490600090610af257610af2611260565b60200260200101516040518363ffffffff1660e01b8152600401610b3692919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610b5057600080fd5b505af1158015610b64573d6000803e3d6000fd5b5050505050565b610b73610cfe565b6040805160c08082018352600454825260055463ffffffff808216602080860191825261ffff640100000000850481168789019081526601000000000000909504841660608089019182526006546080808b0191825260075460ff16151560a0808d019182528d519b8c018e5292518b528b518b8801529851909416898c0152945186169088015251909316928501929092528551918201909552905115158152919260009290820190610c2690610dfe565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610c7f9084906004016111e2565b6020604051808303816000875af1158015610c9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc29190611247565b6009555050565b610cd1610cfe565b610cda81610eba565b50565b60088181548110610ced57600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103ba565b565b6009548314610dec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016103ba565b610df860088383610faf565b50505050565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610e3791511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b3373ffffffffffffffffffffffffffffffffffffffff821603610f39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103ba565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610fea579160200282015b82811115610fea578235825591602001919060010190610fcf565b50610ff6929150610ffa565b5090565b5b80821115610ff65760008155600101610ffb565b803573ffffffffffffffffffffffffffffffffffffffff8116811461103357600080fd5b919050565b6000806040838503121561104b57600080fd5b8235915061105b6020840161100f565b90509250929050565b60008060006040848603121561107957600080fd5b83359250602084013567ffffffffffffffff8082111561109857600080fd5b818601915086601f8301126110ac57600080fd5b8135818111156110bb57600080fd5b8760208260051b85010111156110d057600080fd5b6020830194508093505050509250925092565b6000602082840312156110f557600080fd5b5035919050565b60006020828403121561110e57600080fd5b6111178261100f565b9392505050565b60006020828403121561113057600080fd5b8151801515811461111757600080fd5b6000815180845260005b818110156111665760208185018101518683018201520161114a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006111d96060830184611140565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261123f60e0840182611140565b949350505050565b60006020828403121561125957600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c6343000813000a",
}
var VRFV2PlusSingleConsumerExampleABI = VRFV2PlusSingleConsumerExampleMetaData.ABI
diff --git a/core/gethwrappers/generated/vrf_v2plus_sub_owner/vrf_v2plus_sub_owner.go b/core/gethwrappers/generated/vrf_v2plus_sub_owner/vrf_v2plus_sub_owner.go
index 8354b68d766..b2c22e8919b 100644
--- a/core/gethwrappers/generated/vrf_v2plus_sub_owner/vrf_v2plus_sub_owner.go
+++ b/core/gethwrappers/generated/vrf_v2plus_sub_owner/vrf_v2plus_sub_owner.go
@@ -32,7 +32,7 @@ var (
var VRFV2PlusExternalSubOwnerExampleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorSet\",\"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\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x608060405234801561001057600080fd5b50604051610def380380610def83398101604081905261002f916101e6565b8133806000816100865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b6576100b681610121565b5050506001600160a01b0381166100e05760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039283166001600160a01b0319918216179091556003805493909216928116929092179055600680549091163317905550610219565b336001600160a01b038216036101795760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146101e157600080fd5b919050565b600080604083850312156101f957600080fd5b610202836101ca565b9150610210602084016101ca565b90509250929050565b610bc7806102286000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638ea9811711610076578063e89e106a1161005b578063e89e106a1461014f578063f2fde38b14610166578063f6eaffc81461017957600080fd5b80638ea981171461011c5780639eccacf61461012f57600080fd5b80631fe543e3146100a85780635b6c5de8146100bd57806379ba5097146100d05780638da5cb5b146100d8575b600080fd5b6100bb6100b6366004610918565b61018c565b005b6100bb6100cb366004610a19565b610212565b6100bb610316565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100bb61012a366004610a91565b610413565b6002546100f29073ffffffffffffffffffffffffffffffffffffffff1681565b61015860055481565b604051908152602001610113565b6100bb610174366004610a91565b61059d565b610158610187366004610ace565b6105b1565b60025473ffffffffffffffffffffffffffffffffffffffff163314610204576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61020e82826105d2565b5050565b61021a610655565b60006040518060c001604052808481526020018881526020018661ffff1681526020018763ffffffff1681526020018563ffffffff16815260200161026e60405180602001604052808615158152506106d8565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e906102c7908490600401610ae7565b6020604051808303816000875af11580156102e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030a9190610ba1565b60055550505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016101fb565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610453575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156104d7573361047860005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016101fb565b73ffffffffffffffffffffffffffffffffffffffff8116610524576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b6105a5610655565b6105ae81610794565b50565b600481815481106105c157600080fd5b600091825260209091200154905081565b600554821461063d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016101fb565b8051610650906004906020840190610889565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016101fb565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161071191511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b3373ffffffffffffffffffffffffffffffffffffffff821603610813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016101fb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8280548282559060005260206000209081019282156108c4579160200282015b828111156108c45782518255916020019190600101906108a9565b506108d09291506108d4565b5090565b5b808211156108d057600081556001016108d5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561092b57600080fd5b8235915060208084013567ffffffffffffffff8082111561094b57600080fd5b818601915086601f83011261095f57600080fd5b813581811115610971576109716108e9565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811085821117156109b4576109b46108e9565b6040529182528482019250838101850191898311156109d257600080fd5b938501935b828510156109f0578435845293850193928501926109d7565b8096505050505050509250929050565b803563ffffffff81168114610a1457600080fd5b919050565b60008060008060008060c08789031215610a3257600080fd5b86359550610a4260208801610a00565b9450604087013561ffff81168114610a5957600080fd5b9350610a6760608801610a00565b92506080870135915060a08701358015158114610a8357600080fd5b809150509295509295509295565b600060208284031215610aa357600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610ac757600080fd5b9392505050565b600060208284031215610ae057600080fd5b5035919050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b81811015610b5e5782810184015186820161010001528301610b41565b5061010092506000838287010152827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116860101935050505092915050565b600060208284031215610bb357600080fd5b505191905056fea164736f6c6343000813000a",
+ Bin: "0x608060405234801561001057600080fd5b50604051610d53380380610d5383398101604081905261002f916101e6565b8133806000816100865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b6576100b681610121565b5050506001600160a01b0381166100e05760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039283166001600160a01b0319918216179091556003805493909216928116929092179055600680549091163317905550610219565b336001600160a01b038216036101795760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146101e157600080fd5b919050565b600080604083850312156101f957600080fd5b610202836101ca565b9150610210602084016101ca565b90509250929050565b610b2b806102286000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638ea9811711610076578063e89e106a1161005b578063e89e106a1461014f578063f2fde38b14610166578063f6eaffc81461017957600080fd5b80638ea981171461011c5780639eccacf61461012f57600080fd5b80631fe543e3146100a85780635b6c5de8146100bd57806379ba5097146100d05780638da5cb5b146100d8575b600080fd5b6100bb6100b63660046108e5565b61018c565b005b6100bb6100cb36600461097d565b610214565b6100bb610318565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100bb61012a3660046109f5565b610415565b6002546100f29073ffffffffffffffffffffffffffffffffffffffff1681565b61015860055481565b604051908152602001610113565b6100bb6101743660046109f5565b61059f565b610158610187366004610a32565b6105b3565b60025473ffffffffffffffffffffffffffffffffffffffff163314610204576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61020f8383836105d4565b505050565b61021c610651565b60006040518060c001604052808481526020018881526020018661ffff1681526020018763ffffffff1681526020018563ffffffff16815260200161027060405180602001604052808615158152506106d4565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e906102c9908490600401610a4b565b6020604051808303816000875af11580156102e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030c9190610b05565b60055550505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016101fb565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610455575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156104d9573361047a60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016101fb565b73ffffffffffffffffffffffffffffffffffffffff8116610526576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b6105a7610651565b6105b081610790565b50565b600481815481106105c357600080fd5b600091825260209091200154905081565b600554831461063f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016101fb565b61064b60048383610885565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016101fb565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161070d91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b3373ffffffffffffffffffffffffffffffffffffffff82160361080f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016101fb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8280548282559060005260206000209081019282156108c0579160200282015b828111156108c05782358255916020019190600101906108a5565b506108cc9291506108d0565b5090565b5b808211156108cc57600081556001016108d1565b6000806000604084860312156108fa57600080fd5b83359250602084013567ffffffffffffffff8082111561091957600080fd5b818601915086601f83011261092d57600080fd5b81358181111561093c57600080fd5b8760208260051b850101111561095157600080fd5b6020830194508093505050509250925092565b803563ffffffff8116811461097857600080fd5b919050565b60008060008060008060c0878903121561099657600080fd5b863595506109a660208801610964565b9450604087013561ffff811681146109bd57600080fd5b93506109cb60608801610964565b92506080870135915060a087013580151581146109e757600080fd5b809150509295509295509295565b600060208284031215610a0757600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610a2b57600080fd5b9392505050565b600060208284031215610a4457600080fd5b5035919050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b81811015610ac25782810184015186820161010001528301610aa5565b5061010092506000838287010152827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116860101935050505092915050565b600060208284031215610b1757600080fd5b505191905056fea164736f6c6343000813000a",
}
var VRFV2PlusExternalSubOwnerExampleABI = VRFV2PlusExternalSubOwnerExampleMetaData.ABI
diff --git a/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go
index 79861507e14..a3ef3b83e43 100644
--- a/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go
+++ b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go
@@ -30,15 +30,6 @@ var (
_ = abi.ConvertType
)
-type VRFCoordinatorV2PlusUpgradedVersionRequestCommitment struct {
- BlockNum uint64
- SubId *big.Int
- CallbackGasLimit uint32
- NumWords uint32
- Sender common.Address
- ExtraArgs []byte
-}
-
type VRFProof struct {
Pk [2]*big.Int
Gamma [2]*big.Int
@@ -51,6 +42,15 @@ type VRFProof struct {
ZInv *big.Int
}
+type VRFTypesRequestCommitmentV2Plus struct {
+ BlockNum uint64
+ SubId *big.Int
+ CallbackGasLimit uint32
+ NumWords uint32
+ Sender common.Address
+ ExtraArgs []byte
+}
+
type VRFV2PlusClientRandomWordsRequest struct {
KeyHash [32]byte
SubId *big.Int
@@ -61,8 +61,8 @@ type VRFV2PlusClientRandomWordsRequest struct {
}
var VRFCoordinatorV2PlusUpgradedVersionMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"expectedVersion\",\"type\":\"uint8\"}],\"name\":\"InvalidVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIDCollisionFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"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\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60a06040523480156200001157600080fd5b5060405162005e3438038062005e3483398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b608051615c61620001d3600039600081816104f401526134790152615c616000f3fe6080604052600436106101e05760003560e01c8062012291146101e5578063088070f5146102125780630ae09540146102e057806315c48b841461030257806318e3dd271461032a5780631b6b6d2314610369578063294daa49146103965780632f622e6b146103b2578063301f42e9146103d2578063405b84fa146103f257806340d6bb821461041257806341af6c871461043d57806351cff8d91461046d5780635d06b4ab1461048d57806364d51a2a146104ad57806365982744146104c2578063689c4517146104e257806372e9d5651461051657806379ba5097146105365780637bce14d11461054b5780638402595e1461056b57806386fe91c71461058b5780638da5cb5b146105ab57806395b55cfc146105c95780639b1c385e146105dc5780639d40a6fd1461060a578063a21a23e414610637578063a4c0ed361461064c578063a63e0bfb1461066c578063aa433aff1461068c578063aefb212f146106ac578063b2a7cac5146106d9578063bec4c08c146106f9578063caf70c4a14610719578063cb63179714610739578063ce3f471914610759578063d98e620e1461076c578063dac83d291461078c578063dc311dd3146107ac578063e72f6e30146107dd578063ee9d2d38146107fd578063f2fde38b1461082a575b600080fd5b3480156101f157600080fd5b506101fa61084a565b60405161020993929190614c80565b60405180910390f35b34801561021e57600080fd5b50600c546102839061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e08401521661010082015261012001610209565b3480156102ec57600080fd5b506103006102fb366004614cff565b6108c6565b005b34801561030e57600080fd5b5061031760c881565b60405161ffff9091168152602001610209565b34801561033657600080fd5b50600a5461035190600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610209565b34801561037557600080fd5b50600254610389906001600160a01b031681565b6040516102099190614d2f565b3480156103a257600080fd5b5060405160028152602001610209565b3480156103be57600080fd5b506103006103cd366004614d43565b61090e565b3480156103de57600080fd5b506103516103ed366004614f9d565b610a5d565b3480156103fe57600080fd5b5061030061040d366004614cff565b610ef3565b34801561041e57600080fd5b506104286101f481565b60405163ffffffff9091168152602001610209565b34801561044957600080fd5b5061045d61045836600461508b565b6112b5565b6040519015158152602001610209565b34801561047957600080fd5b50610300610488366004614d43565b61145b565b34801561049957600080fd5b506103006104a8366004614d43565b6115dd565b3480156104b957600080fd5b50610317606481565b3480156104ce57600080fd5b506103006104dd3660046150a4565b611694565b3480156104ee57600080fd5b506103897f000000000000000000000000000000000000000000000000000000000000000081565b34801561052257600080fd5b50600354610389906001600160a01b031681565b34801561054257600080fd5b506103006116f4565b34801561055757600080fd5b506103006105663660046150d2565b61179e565b34801561057757600080fd5b50610300610586366004614d43565b611897565b34801561059757600080fd5b50600a54610351906001600160601b031681565b3480156105b757600080fd5b506000546001600160a01b0316610389565b6103006105d736600461508b565b6119a3565b3480156105e857600080fd5b506105fc6105f73660046150fa565b611ac4565b604051908152602001610209565b34801561061657600080fd5b5060075461062a906001600160401b031681565b6040516102099190615134565b34801561064357600080fd5b506105fc611e95565b34801561065857600080fd5b50610300610667366004615190565b612068565b34801561067857600080fd5b5061030061068736600461520e565b6121e2565b34801561069857600080fd5b506103006106a736600461508b565b6123eb565b3480156106b857600080fd5b506106cc6106c73660046152af565b612433565b604051610209919061530c565b3480156106e557600080fd5b506103006106f436600461508b565b612535565b34801561070557600080fd5b50610300610714366004614cff565b61262a565b34801561072557600080fd5b506105fc61073436600461531f565b61271c565b34801561074557600080fd5b50610300610754366004614cff565b61274c565b61030061076736600461533b565b6129b6565b34801561077857600080fd5b506105fc61078736600461508b565b612d26565b34801561079857600080fd5b506103006107a7366004614cff565b612d47565b3480156107b857600080fd5b506107cc6107c736600461508b565b612ddd565b6040516102099594939291906153b5565b3480156107e957600080fd5b506103006107f8366004614d43565b612ecb565b34801561080957600080fd5b506105fc61081836600461508b565b600f6020526000908152604090205481565b34801561083657600080fd5b50610300610845366004614d43565b613088565b600c54600e805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff169391928391908301828280156108b457602002820191906000526020600020905b8154815260200190600101908083116108a0575b50505050509050925092509250909192565b816108d08161309c565b6108d86130fd565b6108e1836112b5565b156108ff57604051631685ecdd60e31b815260040160405180910390fd5b610909838361312a565b505050565b6109166130fd565b61091e6132cf565b600b54600160601b90046001600160601b031660000361095157604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c6109748380615420565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b03166109bc9190615420565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610a36576040519150601f19603f3d011682016040523d82523d6000602084013e610a3b565b606091505b50509050806109095760405163950b247960e01b815260040160405180910390fd5b6000610a676130fd565b60005a90506000610a788686613322565b90506000856060015163ffffffff166001600160401b03811115610a9e57610a9e614d60565b604051908082528060200260200182016040528015610ac7578160200160208202803683370190505b50905060005b866060015163ffffffff16811015610b3e57826040015181604051602001610af6929190615440565b6040516020818303038152906040528051906020012060001c828281518110610b2157610b2161544e565b602090810291909101015280610b3681615464565b915050610acd565b50602080830180516000908152600f9092526040808320839055905190518291631fe543e360e01b91610b769190869060240161547d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b1790559089015160808a0151919250600091610bdb9163ffffffff169084613582565b600c805460ff60301b1916905560208a810151600090815260069091526040902054909150600160c01b90046001600160401b0316610c1b816001615496565b6020808c0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08b01518051610c68906001906154b6565b81518110610c7857610c7861544e565b602091010151600c5460f89190911c6001149150600090610ca9908a90600160581b900463ffffffff163a856135ce565b90508115610da1576020808d01516000908152600690915260409020546001600160601b03808316600160601b909204161015610cf957604051631e9acf1760e31b815260040160405180910390fd5b60208c81015160009081526006909152604090208054829190600c90610d30908490600160601b90046001600160601b0316615420565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600b600c8282829054906101000a90046001600160601b0316610d7891906154c9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610e7c565b6020808d01516000908152600690915260409020546001600160601b0380831691161015610de257604051631e9acf1760e31b815260040160405180910390fd5b6020808d015160009081526006909152604081208054839290610e0f9084906001600160601b0316615420565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600b60008282829054906101000a90046001600160601b0316610e5791906154c9565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8b6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051610ed9939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b9392505050565b610efb6130fd565b610f048161361d565b610f2c5780604051635428d44960e01b8152600401610f239190614d2f565b60405180910390fd5b600080600080610f3b86612ddd565b945094505093509350336001600160a01b0316826001600160a01b031614610f9e5760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610f23565b610fa7866112b5565b15610fed5760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610f23565b60006040518060c00160405280611002600290565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b0316815250905060008160405160200161105691906154e9565b604051602081830303815290604052905061107088613686565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b038816906110a99085906004016155ae565b6000604051808303818588803b1580156110c257600080fd5b505af11580156110d6573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506110ff905057506001600160601b03861615155b156111ba5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611136908a908a906004016155c1565b6020604051808303816000875af1158015611155573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117991906155e3565b6111ba5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610f23565b600c805460ff60301b1916600160301b17905560005b8351811015611263578381815181106111eb576111eb61544e565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b815260040161121e9190614d2f565b600060405180830381600087803b15801561123857600080fd5b505af115801561124c573d6000803e3d6000fd5b50505050808061125b90615464565b9150506111d0565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906112a39089908b90615600565b60405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561133f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611321575b505050505081525050905060005b8160400151518110156114515760005b600e5481101561143e576000611407600e838154811061137f5761137f61544e565b9060005260206000200154856040015185815181106113a0576113a061544e565b60200260200101518860046000896040015189815181106113c3576113c361544e565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208d825290925290205461010090046001600160401b031661382e565b506000818152600f60205260409020549091501561142b5750600195945050505050565b508061143681615464565b91505061135d565b508061144981615464565b91505061134d565b5060009392505050565b6114636130fd565b61146b6132cf565b6002546001600160a01b03166114945760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166000036114c057604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006114dc8380615420565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166115249190615420565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061157990859085906004016155c1565b6020604051808303816000875af1158015611598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bc91906155e3565b6115d957604051631e9acf1760e31b815260040160405180910390fd5b5050565b6115e56132cf565b6115ee8161361d565b1561160e578060405163ac8a27ef60e01b8152600401610f239190614d2f565b601280546001810182556000919091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af0162590611689908390614d2f565b60405180910390a150565b61169c6132cf565b6002546001600160a01b0316156116c657604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b031633146117475760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610f23565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6117a66132cf565b6040805180820182526000916117d591908490600290839083908082843760009201919091525061271c915050565b6000818152600d602052604090205490915060ff161561180b57604051634a0b8fa760e01b815260048101829052602401610f23565b6000818152600d6020526040808220805460ff19166001908117909155600e805491820181559092527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd909101829055517fc9583fd3afa3d7f16eb0b88d0268e7d05c09bafa4b21e092cbd1320e1bc8089d9061188b9083815260200190565b60405180910390a15050565b61189f6132cf565b600a544790600160601b90046001600160601b0316818111156118d95780826040516354ced18160e11b8152600401610f23929190615440565b818110156109095760006118ed82846154b6565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d806000811461193c576040519150601f19603f3d011682016040523d82523d6000602084013e611941565b606091505b50509050806119635760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c8583604051611994929190615600565b60405180910390a15050505050565b6119ab6130fd565b6000818152600560205260409020546001600160a01b03166119e057604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611a0f83856154c9565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611a5791906154c9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611aaa9190615619565b604051611ab8929190615440565b60405180910390a25050565b6000611ace6130fd565b6020808301356000908152600590915260409020546001600160a01b0316611b0957604051630fb532db60e11b815260040160405180910390fd5b336000908152600460209081526040808320858301358452808352928190208151606081018352905460ff811615158083526001600160401b036101008304811695840195909552600160481b9091049093169181019190915290611b89578360200135336040516379bfd40160e01b8152600401610f2392919061562c565b600c5461ffff16611ba06060860160408701615643565b61ffff161080611bc3575060c8611bbd6060860160408701615643565b61ffff16115b15611bfd57611bd86060850160408601615643565b600c5460405163539c34bb60e11b8152610f23929161ffff169060c89060040161565e565b600c5462010000900463ffffffff16611c1c608086016060870161567c565b63ffffffff161115611c6257611c38608085016060860161567c565b600c54604051637aebf00f60e11b8152610f23929162010000900463ffffffff1690600401615697565b6101f4611c7560a086016080870161567c565b63ffffffff161115611caf57611c9160a085016080860161567c565b6101f46040516311ce1afb60e21b8152600401610f23929190615697565b806020018051611cbe906156ae565b6001600160401b031690526020818101516000918291611ce69188359133918a01359061382e565b90925090506000611d02611cfd60a08901896156dc565b6138b7565b90506000611d0f82613938565b905083611d1a6139a9565b60208a0135611d2f60808c0160608d0161567c565b611d3f60a08d0160808e0161567c565b3386604051602001611d579796959493929190615722565b60405160208183030381529060405280519060200120600f600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190611dce9190615643565b8e6060016020810190611de1919061567c565b8f6080016020810190611df4919061567c565b89604051611e079695949392919061576e565b60405180910390a45050336000908152600460209081526040808320898301358452825291829020855181549287015193909601516001600160401b03908116600160481b02600160481b600160881b03199190941661010002610100600160481b0319971515979097166001600160481b031990931692909217959095171617909255925050505b919050565b6000611e9f6130fd565b6007546001600160401b031633611eb76001436154b6565b6040516001600160601b0319606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f1981840301815291905280516020909101209150611f1c816001615496565b600780546001600160401b0319166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b9190921602176001600160c01b0316600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b03928316178355935160018301805490951691161790925592518051929493919261201a9260028501920190614b8e565b5061202a91506008905084613a2a565b50827f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d3360405161205b9190614d2f565b60405180910390a2505090565b6120706130fd565b6002546001600160a01b0316331461209b576040516344b0e3c360e01b815260040160405180910390fd5b602081146120bc57604051638129bbcd60e01b815260040160405180910390fd5b60006120ca8284018461508b565b6000818152600560205260409020549091506001600160a01b031661210257604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061212983856154c9565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b031661217191906154c9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846121c49190615619565b6040516121d2929190615440565b60405180910390a2505050505050565b6121ea6132cf565b60c861ffff8a16111561221757888960c860405163539c34bb60e11b8152600401610f239392919061565e565b6000851361223b576040516321ea67b360e11b815260048101869052602401610f23565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b90990298909816600160781b600160b81b0319600160581b90960263ffffffff60581b19600160381b90980297909716600160301b600160781b03196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f95cb2ddab6d2297c29a4861691de69b3969c464aa4a9c44258b101ff02ff375a906123d8908b908b908b908b908b908990899061ffff97909716875263ffffffff95861660208801529385166040870152919093166060850152608084019290925260ff91821660a08401521660c082015260e00190565b60405180910390a1505050505050505050565b6123f36132cf565b6000818152600560205260409020546001600160a01b03168061242957604051630fb532db60e11b815260040160405180910390fd5b6115d9828261312a565b606060006124416008613a36565b905080841061246357604051631390f2a160e01b815260040160405180910390fd5b600061246f8486615619565b90508181118061247d575083155b6124875780612489565b815b9050600061249786836154b6565b9050806001600160401b038111156124b1576124b1614d60565b6040519080825280602002602001820160405280156124da578160200160208202803683370190505b50935060005b8181101561252a576124fd6124f58883615619565b600890613a40565b85828151811061250f5761250f61544e565b602090810291909101015261252381615464565b90506124e0565b505050505b92915050565b61253d6130fd565b6000818152600560205260409020546001600160a01b03168061257357604051630fb532db60e11b815260040160405180910390fd5b6000828152600560205260409020600101546001600160a01b031633146125ca576000828152600560205260409081902060010154905163d084e97560e01b8152610f23916001600160a01b031690600401614d2f565b600082815260056020526040908190208054336001600160a01b031991821681178355600190920180549091169055905183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611ab89185916157ad565b816126348161309c565b61263c6130fd565b6001600160a01b03821660009081526004602090815260408083208684529091529020805460ff161561266f5750505050565b60008481526005602052604090206002018054606319016126a3576040516305a48e0f60e01b815260040160405180910390fd5b8154600160ff1990911681178355815490810182556000828152602090200180546001600160a01b0319166001600160a01b03861617905560405185907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e19061270d908790614d2f565b60405180910390a25050505050565b60008160405160200161272f91906157ea565b604051602081830303815290604052805190602001209050919050565b816127568161309c565b61275e6130fd565b612767836112b5565b1561278557604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b038216600090815260046020908152604080832086845290915290205460ff166127cd5782826040516379bfd40160e01b8152600401610f2392919061562c565b60008381526005602090815260408083206002018054825181850281018501909352808352919290919083018282801561283057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612812575b5050505050905060006001825161284791906154b6565b905060005b825181101561295257846001600160a01b03168382815181106128715761287161544e565b60200260200101516001600160a01b03160361294057600083838151811061289b5761289b61544e565b60200260200101519050806005600089815260200190815260200160002060020183815481106128cd576128cd61544e565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255888152600590915260409020600201805480612918576129186157f8565b600082815260209020810160001990810180546001600160a01b031916905501905550612952565b8061294a81615464565b91505061284c565b506001600160a01b03841660009081526004602090815260408083208884529091529081902080546001600160881b03191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a79061270d908790614d2f565b60006129c482840184615825565b9050806000015160ff166001146129fd57805160405163237d181f60e21b815260ff909116600482015260016024820152604401610f23565b8060a001516001600160601b03163414612a415760a08101516040516306acf13560e41b81523460048201526001600160601b039091166024820152604401610f23565b6020808201516000908152600590915260409020546001600160a01b031615612a7d576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612b7657604051806060016040528060011515815260200160006001600160401b0316815260200160006001600160401b03168152506004600084606001518481518110612ad957612ad961544e565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208684015182528352819020835181549385015194909201516001600160481b0319909316911515610100600160481b031916919091176101006001600160401b039485160217600160481b600160881b031916600160481b939092169290920217905580612b6e81615464565b915050612a80565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612c7592600285019290910190614b8e565b5050506080810151600a8054600090612c989084906001600160601b03166154c9565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612ce491906154c9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612d2081602001516008613a2a90919063ffffffff16565b50505050565b600e8181548110612d3657600080fd5b600091825260209091200154905081565b81612d518161309c565b612d596130fd565b600083815260056020526040902060018101546001600160a01b03848116911614612d20576001810180546001600160a01b0319166001600160a01b03851617905560405184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a190612dcf90339087906157ad565b60405180910390a250505050565b600081815260056020526040812054819081906001600160a01b0316606081612e1957604051630fb532db60e11b815260040160405180910390fd5b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612eb157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612e93575b505050505090509450945094509450945091939590929450565b612ed36132cf565b6002546001600160a01b0316612efc5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612f2d903090600401614d2f565b602060405180830381865afa158015612f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6e9190615950565b600a549091506001600160601b031681811115612fa25780826040516354ced18160e11b8152600401610f23929190615440565b81811015610909576000612fb682846154b6565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612fe99087908590600401615600565b6020604051808303816000875af1158015613008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302c91906155e3565b61304957604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600848260405161307a929190615600565b60405180910390a150505050565b6130906132cf565b61309981613a4c565b50565b6000818152600560205260409020546001600160a01b0316806130d257604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146115d95780604051636c51fda960e11b8152600401610f239190614d2f565b600c54600160301b900460ff16156131285760405163769dd35360e11b815260040160405180910390fd5b565b60008061313684613686565b60025491935091506001600160a01b03161580159061315d57506001600160601b03821615155b156131fd5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061319d9086906001600160601b03871690600401615600565b6020604051808303816000875af11580156131bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e091906155e3565b6131fd57604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613253576040519150601f19603f3d011682016040523d82523d6000602084013e613258565b606091505b505090508061327a5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c49060600161270d565b6000546001600160a01b031633146131285760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610f23565b6040805160608101825260008082526020820181905291810191909152600061334e846000015161271c565b6000818152600d602052604090205490915060ff1661338357604051631dfd6e1360e21b815260048101829052602401610f23565b600081856080015160405160200161339c929190615440565b60408051601f1981840301815291815281516020928301206000818152600f90935290822054909250908190036133e657604051631b44092560e11b815260040160405180910390fd5b845160208087015160408089015160608a015160808b015160a08c01519351613415978a979096959101615969565b60405160208183030381529060405280519060200120811461344a5760405163354a450b60e21b815260040160405180910390fd5b60006134598660000151613aef565b905080613511578551604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d38916134ad9190600401615134565b602060405180830381865afa1580156134ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ee9190615950565b90508061351157855160405163175dadad60e01b8152610f239190600401615134565b6000876080015182604051602001613533929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c9050600061355a8983613bbd565b6040805160608101825297885260208801969096529486019490945250929695505050505050565b60005a61138881101561359457600080fd5b6113888103905084604082048203116135ac57600080fd5b50823b6135b857600080fd5b60008083516020850160008789f1949350505050565b600081156135fb576011546135f49086908690600160201b900463ffffffff1686613c28565b9050613615565b601154613612908690869063ffffffff1686613cca565b90505b949350505050565b6000805b60125481101561367d57826001600160a01b0316601282815481106136485761364861544e565b6000918252602090912001546001600160a01b03160361366b5750600192915050565b8061367581615464565b915050613621565b50600092915050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b8181101561372857600460008483815481106136db576136db61544e565b60009182526020808320909101546001600160a01b031683528281019390935260409182018120898252909252902080546001600160881b031916905561372181615464565b90506136bd565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906137606002830182614bf3565b505060008581526006602052604081205561377c600886613def565b506001600160601b038416156137cf57600a80548591906000906137aa9084906001600160601b0316615420565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156138275782600a600c8282829054906101000a90046001600160601b03166138029190615420565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f198184030181529082905280516020918201209250613893918991849101615440565b60408051808303601f19018152919052805160209091012097909650945050505050565b60408051602081019091526000815260008290036138e4575060408051602081019091526000815261252f565b63125fa26760e31b6138f683856159bd565b6001600160e01b0319161461391e57604051632923fee760e11b815260040160405180910390fd5b61392b82600481866159ed565b810190610eec9190615a17565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161397191511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b6000466139b581613dfb565b15613a235760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156139f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a1d9190615950565b91505090565b4391505090565b6000610eec8383613e1e565b600061252f825490565b6000610eec8383613e6d565b336001600160a01b03821603613a9e5760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610f23565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613afb81613dfb565b15613bae57610100836001600160401b0316613b156139a9565b613b1f91906154b6565b1180613b3b5750613b2e6139a9565b836001600160401b031610155b15613b495750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613b6d908690600401615134565b602060405180830381865afa158015613b8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eec9190615950565b50506001600160401b03164090565b6000613bf18360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613e97565b60038360200151604051602001613c09929190615a62565b60408051601f1981840301815291905280516020909101209392505050565b600080613c6b6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506140b292505050565b905060005a613c7a8888615619565b613c8491906154b6565b613c8e9085615a76565b90506000613ca763ffffffff871664e8d4a51000615a76565b905082613cb48284615619565b613cbe9190615619565b98975050505050505050565b600080613cd561417c565b905060008113613cfb576040516321ea67b360e11b815260048101829052602401610f23565b6000613d3d6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506140b292505050565b9050600082825a613d4e8b8b615619565b613d5891906154b6565b613d629088615a76565b613d6c9190615619565b613d7e90670de0b6b3a7640000615a76565b613d889190615aa3565b90506000613da163ffffffff881664e8d4a51000615a76565b9050613db881676765c793fa10079d601b1b6154b6565b821115613dd85760405163e80fa38160e01b815260040160405180910390fd5b613de28183615619565b9998505050505050505050565b6000610eec8383614238565b600061a4b1821480613e0f575062066eed82145b8061252f57505062066eee1490565b6000818152600183016020526040812054613e655750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561252f565b50600061252f565b6000826000018281548110613e8457613e8461544e565b9060005260206000200154905092915050565b613ea089614332565b613ee95760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610f23565b613ef288614332565b613f365760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610f23565b613f3f83614332565b613f8b5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610f23565b613f9482614332565b613fdf5760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b6044820152606401610f23565b613feb878a88876143f5565b6140335760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610f23565b600061403f8a87614509565b90506000614052898b878b86898961456d565b90506000614063838d8d8a86614680565b9050808a146140a45760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610f23565b505050505050505050505050565b6000466140be81613dfb565b1561410257606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b8a573d6000803e3d6000fd5b61410b816146c0565b1561367d57600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615c0d60489139604051602001614151929190615ab7565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613b6d91906155ae565b600c5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a09291908290030181865afa1580156141df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142039190615afd565b509450909250849150508015614227575061421e82426154b6565b8463ffffffff16105b156136155750601054949350505050565b6000818152600183016020526040812054801561432157600061425c6001836154b6565b8554909150600090614270906001906154b6565b90508181146142d55760008660000182815481106142905761429061544e565b90600052602060002001549050808760000184815481106142b3576142b361544e565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806142e6576142e66157f8565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061252f565b600091505061252f565b5092915050565b80516000906401000003d019116143805760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610f23565b60208201516401000003d019116143ce5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610f23565b60208201516401000003d0199080096143ee8360005b60200201516146fa565b1492915050565b60006001600160a01b03821661443b5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610f23565b60208401516000906001161561445257601c614455565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020909101918290529293506001916144bf91869188918790615b4d565b6020604051602081039080840390855afa1580156144e1573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614511614c11565b61453e6001848460405160200161452a93929190615b6b565b60405160208183030381529060405261471e565b90505b61454a81614332565b61252f578051604080516020810192909252614566910161452a565b9050614541565b614575614c11565b825186516401000003d01991829006919006036145d45760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610f23565b6145df87898861476b565b6146245760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610f23565b61462f84868561476b565b6146755760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610f23565b613cbe868484614889565b60006002868686858760405160200161469e96959493929190615b8c565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a8214806146d257506101a482145b806146df575062aa37dc82145b806146eb575061210582145b8061252f57505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614726614c11565b61472f8261494c565b815261474461473f8260006143e4565b614987565b6020820181905260029006600103611e90576020810180516401000003d019039052919050565b6000826000036147ab5760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610f23565b835160208501516000906147c190600290615be6565b156147cd57601c6147d0565b601b5b9050600070014551231950b75fc4402da1732fc9bebe19838709604080516000808252602090910191829052919250600190614813908390869088908790615b4d565b6020604051602081039080840390855afa158015614835573d6000803e3d6000fd5b5050506020604051035190506000866040516020016148549190615bfa565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614891614c11565b8351602080860151855191860151600093849384936148b2939091906149a7565b919450925090506401000003d01985820960011461490e5760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610f23565b60405180604001604052806401000003d0198061492d5761492d615a8d565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611e9057604080516020808201939093528151808203840181529082019091528051910120614954565b600061252f8260026149a06401000003d0196001615619565b901c614a87565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a08905060006149e783838585614b21565b90985090506149f888828e88614b45565b9098509050614a0988828c87614b45565b90985090506000614a1c8d878b85614b45565b9098509050614a2d88828686614b21565b9098509050614a3e88828e89614b45565b9098509050818114614a73576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614a77565b8196505b5050505050509450945094915050565b600080614a92614c2f565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614ac4614c4d565b60208160c0846005600019fa925082600003614b175760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610f23565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614be3579160200282015b82811115614be357825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614bae565b50614bef929150614c6b565b5090565b50805460008255906000526020600020908101906130999190614c6b565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614bef5760008155600101614c6c565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015614cd157845183529383019391830191600101614cb5565b509098975050505050505050565b6001600160a01b038116811461309957600080fd5b8035611e9081614cdf565b60008060408385031215614d1257600080fd5b823591506020830135614d2481614cdf565b809150509250929050565b6001600160a01b0391909116815260200190565b600060208284031215614d5557600080fd5b8135610eec81614cdf565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715614d9857614d98614d60565b60405290565b60405161012081016001600160401b0381118282101715614d9857614d98614d60565b604051601f8201601f191681016001600160401b0381118282101715614de957614de9614d60565b604052919050565b600082601f830112614e0257600080fd5b604080519081016001600160401b0381118282101715614e2457614e24614d60565b8060405250806040840185811115614e3b57600080fd5b845b81811015614e55578035835260209283019201614e3d565b509195945050505050565b803563ffffffff81168114611e9057600080fd5b600082601f830112614e8557600080fd5b81356001600160401b03811115614e9e57614e9e614d60565b614eb1601f8201601f1916602001614dc1565b818152846020838601011115614ec657600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614ef557600080fd5b614efd614d76565b905081356001600160401b038082168214614f1757600080fd5b81835260208401356020840152614f3060408501614e60565b6040840152614f4160608501614e60565b6060840152614f5260808501614cf4565b608084015260a0840135915080821115614f6b57600080fd5b50614f7884828501614e74565b60a08301525092915050565b801515811461309957600080fd5b8035611e9081614f84565b60008060008385036101e0811215614fb457600080fd5b6101a080821215614fc457600080fd5b614fcc614d9e565b9150614fd88787614df1565b8252614fe78760408801614df1565b60208301526080860135604083015260a0860135606083015260c0860135608083015261501660e08701614cf4565b60a083015261010061502a88828901614df1565b60c084015261503d886101408901614df1565b60e0840152610180870135908301529093508401356001600160401b0381111561506657600080fd5b61507286828701614ee3565b9250506150826101c08501614f92565b90509250925092565b60006020828403121561509d57600080fd5b5035919050565b600080604083850312156150b757600080fd5b82356150c281614cdf565b91506020830135614d2481614cdf565b6000604082840312156150e457600080fd5b826040830111156150f457600080fd5b50919050565b60006020828403121561510c57600080fd5b81356001600160401b0381111561512257600080fd5b820160c08185031215610eec57600080fd5b6001600160401b0391909116815260200190565b60008083601f84011261515a57600080fd5b5081356001600160401b0381111561517157600080fd5b60208301915083602082850101111561518957600080fd5b9250929050565b600080600080606085870312156151a657600080fd5b84356151b181614cdf565b93506020850135925060408501356001600160401b038111156151d357600080fd5b6151df87828801615148565b95989497509550505050565b803561ffff81168114611e9057600080fd5b803560ff81168114611e9057600080fd5b60008060008060008060008060006101208a8c03121561522d57600080fd5b6152368a6151eb565b985061524460208b01614e60565b975061525260408b01614e60565b965061526060608b01614e60565b955060808a0135945061527560a08b01614e60565b935061528360c08b01614e60565b925061529160e08b016151fd565b91506152a06101008b016151fd565b90509295985092959850929598565b600080604083850312156152c257600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015615301578151875295820195908201906001016152e5565b509495945050505050565b602081526000610eec60208301846152d1565b60006040828403121561533157600080fd5b610eec8383614df1565b6000806020838503121561534e57600080fd5b82356001600160401b0381111561536457600080fd5b61537085828601615148565b90969095509350505050565b600081518084526020808501945080840160005b838110156153015781516001600160a01b031687529582019590820190600101615390565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a0608082018190526000906153ff9083018461537c565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6001600160601b0382811682821603908082111561432b5761432b61540a565b918252602082015260400190565b634e487b7160e01b600052603260045260246000fd5b6000600182016154765761547661540a565b5060010190565b82815260406020820152600061361560408301846152d1565b6001600160401b0381811683821601908082111561432b5761432b61540a565b8181038181111561252f5761252f61540a565b6001600160601b0381811683821601908082111561432b5761432b61540a565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261552e60e084018261537c565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b60005b83811015615579578181015183820152602001615561565b50506000910152565b6000815180845261559a81602086016020860161555e565b601f01601f19169290920160200192915050565b602081526000610eec6020830184615582565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6000602082840312156155f557600080fd5b8151610eec81614f84565b6001600160a01b03929092168252602082015260400190565b8082018082111561252f5761252f61540a565b9182526001600160a01b0316602082015260400190565b60006020828403121561565557600080fd5b610eec826151eb565b61ffff93841681529183166020830152909116604082015260600190565b60006020828403121561568e57600080fd5b610eec82614e60565b63ffffffff92831681529116602082015260400190565b60006001600160401b038281166002600160401b031981016156d2576156d261540a565b6001019392505050565b6000808335601e198436030181126156f357600080fd5b8301803591506001600160401b0382111561570d57600080fd5b60200191503681900382131561518957600080fd5b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613de290830184615582565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a0830152613cbe60c0830184615582565b6001600160a01b0392831681529116602082015260400190565b8060005b6002811015612d205781518452602093840193909101906001016157cb565b6040810161252f82846157c7565b634e487b7160e01b600052603160045260246000fd5b80356001600160601b0381168114611e9057600080fd5b6000602080838503121561583857600080fd5b82356001600160401b038082111561584f57600080fd5b9084019060c0828703121561586357600080fd5b61586b614d76565b615874836151fd565b81528383013584820152604083013561588c81614cdf565b60408201526060830135828111156158a357600080fd5b8301601f810188136158b457600080fd5b8035838111156158c6576158c6614d60565b8060051b93506158d7868501614dc1565b818152938201860193868101908a8611156158f157600080fd5b928701925b8584101561591b578335925061590b83614cdf565b82825292870192908701906158f6565b6060850152506159309150506080840161580e565b608082015261594160a0840161580e565b60a08201529695505050505050565b60006020828403121561596257600080fd5b5051919050565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613de290830184615582565b6001600160e01b031981358181169160048510156159e55780818660040360031b1b83161692505b505092915050565b600080858511156159fd57600080fd5b83861115615a0a57600080fd5b5050820193919092039150565b600060208284031215615a2957600080fd5b604051602081016001600160401b0381118282101715615a4b57615a4b614d60565b6040528235615a5981614f84565b81529392505050565b82815260608101610eec60208301846157c7565b808202811582820484141761252f5761252f61540a565b634e487b7160e01b600052601260045260246000fd5b600082615ab257615ab2615a8d565b500490565b60008351615ac981846020880161555e565b835190830190615add81836020880161555e565b01949350505050565b80516001600160501b0381168114611e9057600080fd5b600080600080600060a08688031215615b1557600080fd5b615b1e86615ae6565b9450602086015193506040860151925060608601519150615b4160808701615ae6565b90509295509295909350565b93845260ff9290921660208401526040830152606082015260800190565b838152615b7b60208201846157c7565b606081019190915260800192915050565b868152615b9c60208201876157c7565b615ba960608201866157c7565b615bb660a08201856157c7565b615bc360e08201846157c7565b60609190911b6001600160601b0319166101208201526101340195945050505050565b600082615bf557615bf5615a8d565b500690565b615c0481836157c7565b60400191905056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxGas\",\"type\":\"uint256\"}],\"name\":\"GasPriceExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"max\",\"type\":\"uint8\"}],\"name\":\"InvalidPremiumPercentage\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"expectedVersion\",\"type\":\"uint8\"}],\"name\":\"InvalidVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"max\",\"type\":\"uint32\"}],\"name\":\"MsgDataTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIDCollisionFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"}],\"name\":\"FallbackWeiPerUnitLinkUsed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"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\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFTypes.RequestCommitmentV2Plus\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x60a06040523480156200001157600080fd5b506040516200613f3803806200613f83398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b608051615f6c620001d36000396000818161052e01526133610152615f6c6000f3fe6080604052600436106101f65760003560e01c8062012291146101fb578063043bd6ae14610228578063088070f51461024c5780630ae095401461031a57806315c48b841461033c57806318e3dd27146103645780631b6b6d23146103a3578063294daa49146103d05780632f622e6b146103ec578063301f42e91461040c578063405b84fa1461042c57806340d6bb821461044c57806341af6c871461047757806351cff8d9146104a75780635d06b4ab146104c757806364d51a2a146104e757806365982744146104fc578063689c45171461051c57806372e9d5651461055057806379ba5097146105705780637a5a2aef146105855780638402595e146105a557806386fe91c7146105c55780638da5cb5b146105e557806395b55cfc146106035780639b1c385e146106165780639d40a6fd14610636578063a21a23e414610663578063a4c0ed3614610678578063a63e0bfb14610698578063aa433aff146106b8578063aefb212f146106d8578063b2a7cac514610705578063bec4c08c14610725578063caf70c4a14610745578063cb63179714610765578063ce3f471914610785578063d98e620e14610798578063da2f2610146107b8578063dac83d2914610817578063dc311dd314610837578063e72f6e3014610868578063ee9d2d3814610888578063f2fde38b146108b5575b600080fd5b34801561020757600080fd5b506102106108d5565b60405161021f93929190614eeb565b60405180910390f35b34801561023457600080fd5b5061023e60105481565b60405190815260200161021f565b34801561025857600080fd5b50600c546102bd9061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e0840152166101008201526101200161021f565b34801561032657600080fd5b5061033a610335366004614f6a565b610951565b005b34801561034857600080fd5b5061035160c881565b60405161ffff909116815260200161021f565b34801561037057600080fd5b50600a5461038b90600160601b90046001600160601b031681565b6040516001600160601b03909116815260200161021f565b3480156103af57600080fd5b506002546103c3906001600160a01b031681565b60405161021f9190614f9a565b3480156103dc57600080fd5b506040516002815260200161021f565b3480156103f857600080fd5b5061033a610407366004614fae565b610999565b34801561041857600080fd5b5061038b6104273660046151fd565b610ae8565b34801561043857600080fd5b5061033a610447366004614f6a565b610e02565b34801561045857600080fd5b506104626101f481565b60405163ffffffff909116815260200161021f565b34801561048357600080fd5b506104976104923660046152eb565b6111a5565b604051901515815260200161021f565b3480156104b357600080fd5b5061033a6104c2366004614fae565b611259565b3480156104d357600080fd5b5061033a6104e2366004614fae565b6113db565b3480156104f357600080fd5b50610351606481565b34801561050857600080fd5b5061033a610517366004615304565b611492565b34801561052857600080fd5b506103c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561055c57600080fd5b506003546103c3906001600160a01b031681565b34801561057c57600080fd5b5061033a6114f2565b34801561059157600080fd5b5061033a6105a0366004615332565b61159c565b3480156105b157600080fd5b5061033a6105c0366004614fae565b6116d8565b3480156105d157600080fd5b50600a5461038b906001600160601b031681565b3480156105f157600080fd5b506000546001600160a01b03166103c3565b61033a6106113660046152eb565b6117e4565b34801561062257600080fd5b5061023e61063136600461536c565b611905565b34801561064257600080fd5b50600754610656906001600160401b031681565b60405161021f91906153a6565b34801561066f57600080fd5b5061023e611cbf565b34801561068457600080fd5b5061033a610693366004615402565b611e92565b3480156106a457600080fd5b5061033a6106b3366004615480565b61200c565b3480156106c457600080fd5b5061033a6106d33660046152eb565b6122ae565b3480156106e457600080fd5b506106f86106f3366004615521565b6122f6565b60405161021f919061557e565b34801561071157600080fd5b5061033a6107203660046152eb565b6123f8565b34801561073157600080fd5b5061033a610740366004614f6a565b6124ed565b34801561075157600080fd5b5061023e610760366004615591565b6125df565b34801561077157600080fd5b5061033a610780366004614f6a565b61260f565b61033a6107933660046155ad565b612871565b3480156107a457600080fd5b5061023e6107b33660046152eb565b612bd8565b3480156107c457600080fd5b506107f86107d33660046152eb565b600d6020526000908152604090205460ff81169061010090046001600160401b031682565b6040805192151583526001600160401b0390911660208301520161021f565b34801561082357600080fd5b5061033a610832366004614f6a565b612bf9565b34801561084357600080fd5b506108576108523660046152eb565b612c8f565b60405161021f959493929190615627565b34801561087457600080fd5b5061033a610883366004614fae565b612d7d565b34801561089457600080fd5b5061023e6108a33660046152eb565b600f6020526000908152604090205481565b3480156108c157600080fd5b5061033a6108d0366004614fae565b612f3a565b600c54600e805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561093f57602002820191906000526020600020905b81548152602001906001019080831161092b575b50505050509050925092509250909192565b8161095b81612f4e565b610963612faf565b61096c836111a5565b1561098a57604051631685ecdd60e31b815260040160405180910390fd5b6109948383612fdc565b505050565b6109a1612faf565b6109a9613181565b600b54600160601b90046001600160601b03166000036109dc57604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c6109ff8380615692565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610a479190615692565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610ac1576040519150601f19603f3d011682016040523d82523d6000602084013e610ac6565b606091505b50509050806109945760405163950b247960e01b815260040160405180910390fd5b6000610af2612faf565b60005a9050610324361115610b2957604051630f28961b60e01b815236600482015261032460248201526044015b60405180910390fd5b6000610b3586866131d4565b90506000610b4b8583600001516020015161346b565b60408301516060888101519293509163ffffffff16806001600160401b03811115610b7857610b78614fcb565b604051908082528060200260200182016040528015610ba1578160200160208202803683370190505b50925060005b81811015610c08578281604051602001610bc29291906156b2565b6040516020818303038152906040528051906020012060001c848281518110610bed57610bed6156c0565b6020908102919091010152610c01816156d6565b9050610ba7565b5050602080850180516000908152600f9092526040822082905551610c2e908a856134b9565b60208a8101516000908152600690915260409020805491925090601890610c6490600160c01b90046001600160401b03166156ef565b82546101009290920a6001600160401b0381810219909316918316021790915560808a01516001600160a01b03166000908152600460209081526040808320828e01518452909152902080549091600991610cc791600160481b9091041661571d565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555060008960a0015160018b60a0015151610d049190615740565b81518110610d1457610d146156c0565b60209101015160f81c60011490506000610d308887848d613554565b90995090508015610d7b577f6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a8760200151601054604051610d729291906156b2565b60405180910390a15b50610d8b88828c6020015161358c565b6020808b015187820151604080518781526001600160601b038d16948101949094528415159084015284151560608401528b1515608084015290917faeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b79060a00160405180910390a3505050505050505b9392505050565b610e0a612faf565b610e13816136df565b610e325780604051635428d44960e01b8152600401610b209190614f9a565b600080600080610e4186612c8f565b945094505093509350336001600160a01b0316826001600160a01b031614610ea45760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610b20565b610ead866111a5565b15610ef35760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610b20565b6040805160c0810182526001815260208082018990526001600160a01b03851682840152606082018490526001600160601b038088166080840152861660a083015291519091600091610f4891849101615753565b6040516020818303038152906040529050610f628861374a565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b03881690610f9b908590600401615818565b6000604051808303818588803b158015610fb457600080fd5b505af1158015610fc8573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150610ff1905057506001600160601b03861615155b156110ac5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611028908a908a9060040161582b565b6020604051808303816000875af1158015611047573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106b919061584d565b6110ac5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610b20565b600c805460ff60301b1916600160301b17905560005b8351811015611153578381815181106110dd576110dd6156c0565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b81526004016111109190614f9a565b600060405180830381600087803b15801561112a57600080fd5b505af115801561113e573d6000803e3d6000fd5b505050508061114c906156d6565b90506110c2565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906111939089908b9061586a565b60405180910390a15050505050505050565b600081815260056020526040812060020180548083036111c9575060009392505050565b60005b8181101561124e576000600460008584815481106111ec576111ec6156c0565b60009182526020808320909101546001600160a01b0316835282810193909352604091820181208982529092529020546001600160401b03600160481b90910416111561123e57506001949350505050565b611247816156d6565b90506111cc565b506000949350505050565b611261612faf565b611269613181565b6002546001600160a01b03166112925760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166000036112be57604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006112da8380615692565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166113229190615692565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611377908590859060040161582b565b6020604051808303816000875af1158015611396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ba919061584d565b6113d757604051631e9acf1760e31b815260040160405180910390fd5b5050565b6113e3613181565b6113ec816136df565b1561140c578060405163ac8a27ef60e01b8152600401610b209190614f9a565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af0162590611487908390614f9a565b60405180910390a150565b61149a613181565b6002546001600160a01b0316156114c457604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b031633146115455760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610b20565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6115a4613181565b6040805180820182526000916115d39190859060029083908390808284376000920191909152506125df915050565b6000818152600d602052604090205490915060ff161561160957604051634a0b8fa760e01b815260048101829052602401610b20565b60408051808201825260018082526001600160401b0385811660208085019182526000878152600d9091528581209451855492516001600160481b0319909316901515610100600160481b03191617610100929093169190910291909117909255600e805491820181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01829055517f9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd3906116cb9083908590615883565b60405180910390a1505050565b6116e0613181565b600a544790600160601b90046001600160601b03168181111561171a5780826040516354ced18160e11b8152600401610b209291906156b2565b8181101561099457600061172e8284615740565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d806000811461177d576040519150601f19603f3d011682016040523d82523d6000602084013e611782565b606091505b50509050806117a45760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c85836040516117d592919061586a565b60405180910390a15050505050565b6117ec612faf565b6000818152600560205260409020546001600160a01b031661182157604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611850838561589a565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611898919061589a565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e9028234846118eb91906158ba565b6040516118f99291906156b2565b60405180910390a25050565b600061190f612faf565b602080830135600081815260059092526040909120546001600160a01b031661194b57604051630fb532db60e11b815260040160405180910390fd5b336000908152600460209081526040808320848452808352928190208151606081018352905460ff811615158083526001600160401b036101008304811695840195909552600160481b90910490931691810191909152906119c45782336040516379bfd40160e01b8152600401610b209291906158cd565b600c5461ffff166119db60608701604088016158e4565b61ffff1610806119fe575060c86119f860608701604088016158e4565b61ffff16115b15611a3857611a1360608601604087016158e4565b600c5460405163539c34bb60e11b8152610b20929161ffff169060c8906004016158ff565b600c5462010000900463ffffffff16611a57608087016060880161591d565b63ffffffff161115611a9d57611a73608086016060870161591d565b600c54604051637aebf00f60e11b8152610b20929162010000900463ffffffff1690600401615938565b6101f4611ab060a087016080880161591d565b63ffffffff161115611aea57611acc60a086016080870161591d565b6101f46040516311ce1afb60e21b8152600401610b20929190615938565b806020018051611af9906156ef565b6001600160401b03169052604081018051611b13906156ef565b6001600160401b031690526020810151600090611b3690873590339087906138f2565b90955090506000611b5a611b55611b5060a08a018a61594f565b61397b565b6139fc565b905085611b65613a6d565b86611b7660808b0160608c0161591d565b611b8660a08c0160808d0161591d565b3386604051602001611b9e9796959493929190615995565b60405160208183030381529060405280519060200120600f600088815260200190815260200160002081905550336001600160a01b03168588600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e89868c6040016020810190611c1191906158e4565b8d6060016020810190611c24919061591d565b8e6080016020810190611c37919061591d565b89604051611c4a969594939291906159ee565b60405180910390a4505060009283526020918252604092839020815181549383015192909401516001600160481b0319909316931515610100600160481b031916939093176101006001600160401b039283160217600160481b600160881b031916600160481b91909216021790555b919050565b6000611cc9612faf565b6007546001600160401b031633611ce1600143615740565b6040516001600160601b0319606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f1981840301815291905280516020909101209150611d46816001615a2d565b600780546001600160401b0319166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b9190921602176001600160c01b0316600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b039283161783559351600183018054909516911617909255925180519294939192611e449260028501920190614df9565b50611e5491506008905084613aee565b50827f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d33604051611e859190614f9a565b60405180910390a2505090565b611e9a612faf565b6002546001600160a01b03163314611ec5576040516344b0e3c360e01b815260040160405180910390fd5b60208114611ee657604051638129bbcd60e01b815260040160405180910390fd5b6000611ef4828401846152eb565b6000818152600560205260409020549091506001600160a01b0316611f2c57604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b031691869190611f53838561589a565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b0316611f9b919061589a565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a828784611fee91906158ba565b604051611ffc9291906156b2565b60405180910390a2505050505050565b612014613181565b60c861ffff8a16111561204157888960c860405163539c34bb60e11b8152600401610b20939291906158ff565b60008513612065576040516321ea67b360e11b815260048101869052602401610b20565b8363ffffffff168363ffffffff1611156120965782846040516313c06e5960e11b8152600401610b20929190615938565b609b60ff831611156120c05781609b604051631d66288d60e11b8152600401610b20929190615a4d565b609b60ff821611156120ea5780609b604051631d66288d60e11b8152600401610b20929190615a4d565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b90990298909816600160781b600160b81b0319600160581b90960263ffffffff60581b19600160381b90980297909716600160301b600160781b03196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b69061229b908b908b908b908b908b908b908b908b908b9061ffff99909916895263ffffffff97881660208a0152958716604089015293861660608801526080870192909252841660a086015290921660c084015260ff91821660e0840152166101008201526101200190565b60405180910390a1505050505050505050565b6122b6613181565b6000818152600560205260409020546001600160a01b0316806122ec57604051630fb532db60e11b815260040160405180910390fd5b6113d78282612fdc565b606060006123046008613afa565b905080841061232657604051631390f2a160e01b815260040160405180910390fd5b600061233284866158ba565b905081811180612340575083155b61234a578061234c565b815b9050600061235a8683615740565b9050806001600160401b0381111561237457612374614fcb565b60405190808252806020026020018201604052801561239d578160200160208202803683370190505b50935060005b818110156123ed576123c06123b888836158ba565b600890613b04565b8582815181106123d2576123d26156c0565b60209081029190910101526123e6816156d6565b90506123a3565b505050505b92915050565b612400612faf565b6000818152600560205260409020546001600160a01b03168061243657604051630fb532db60e11b815260040160405180910390fd5b6000828152600560205260409020600101546001600160a01b0316331461248d576000828152600560205260409081902060010154905163d084e97560e01b8152610b20916001600160a01b031690600401614f9a565b600082815260056020526040908190208054336001600160a01b031991821681178355600190920180549091169055905183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386916118f9918591615a61565b816124f781612f4e565b6124ff612faf565b6001600160a01b03821660009081526004602090815260408083208684529091529020805460ff16156125325750505050565b6000848152600560205260409020600201805460631901612566576040516305a48e0f60e01b815260040160405180910390fd5b8154600160ff1990911681178355815490810182556000828152602090200180546001600160a01b0319166001600160a01b03861617905560405185907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1906125d0908790614f9a565b60405180910390a25050505050565b6000816040516020016125f29190615a9e565b604051602081830303815290604052805190602001209050919050565b8161261981612f4e565b612621612faf565b61262a836111a5565b1561264857604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b038216600090815260046020908152604080832086845290915290205460ff166126905782826040516379bfd40160e01b8152600401610b209291906158cd565b6000838152600560209081526040808320600201805482518185028101850190935280835291929091908301828280156126f357602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116126d5575b5050505050905060006001825161270a9190615740565b905060005b825181101561281357846001600160a01b0316838281518110612734576127346156c0565b60200260200101516001600160a01b03160361280357600083838151811061275e5761275e6156c0565b6020026020010151905080600560008981526020019081526020016000206002018381548110612790576127906156c0565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558881526005909152604090206002018054806127db576127db615aac565b600082815260209020810160001990810180546001600160a01b031916905501905550612813565b61280c816156d6565b905061270f565b506001600160a01b038416600090815260046020908152604080832088845290915290819020805460ff191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7906125d0908790614f9a565b600061287f82840184615ad9565b9050806000015160ff166001146128af57805160405163237d181f60e21b8152610b209190600190600401615a4d565b8060a001516001600160601b031634146128f35760a08101516040516306acf13560e41b81523460048201526001600160601b039091166024820152604401610b20565b6020808201516000908152600590915260409020546001600160a01b03161561292f576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612a2857604051806060016040528060011515815260200160006001600160401b0316815260200160006001600160401b0316815250600460008460600151848151811061298b5761298b6156c0565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208684015182528352819020835181549385015194909201516001600160481b0319909316911515610100600160481b031916919091176101006001600160401b039485160217600160481b600160881b031916600160481b939092169290920217905580612a20816156d6565b915050612932565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612b2792600285019290910190614df9565b5050506080810151600a8054600090612b4a9084906001600160601b031661589a565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612b96919061589a565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612bd281602001516008613aee90919063ffffffff16565b50505050565b600e8181548110612be857600080fd5b600091825260209091200154905081565b81612c0381612f4e565b612c0b612faf565b600083815260056020526040902060018101546001600160a01b03848116911614612bd2576001810180546001600160a01b0319166001600160a01b03851617905560405184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a190612c819033908790615a61565b60405180910390a250505050565b600081815260056020526040812054819081906001600160a01b0316606081612ccb57604051630fb532db60e11b815260040160405180910390fd5b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612d6357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d45575b505050505090509450945094509450945091939590929450565b612d85613181565b6002546001600160a01b0316612dae5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612ddf903090600401614f9a565b602060405180830381865afa158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e209190615c04565b600a549091506001600160601b031681811115612e545780826040516354ced18160e11b8152600401610b209291906156b2565b81811015610994576000612e688284615740565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612e9b908790859060040161586a565b6020604051808303816000875af1158015612eba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ede919061584d565b612efb57604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366008482604051612f2c92919061586a565b60405180910390a150505050565b612f42613181565b612f4b81613b10565b50565b6000818152600560205260409020546001600160a01b031680612f8457604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146113d75780604051636c51fda960e11b8152600401610b209190614f9a565b600c54600160301b900460ff1615612fda5760405163769dd35360e11b815260040160405180910390fd5b565b600080612fe88461374a565b60025491935091506001600160a01b03161580159061300f57506001600160601b03821615155b156130af5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061304f9086906001600160601b0387169060040161586a565b6020604051808303816000875af115801561306e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613092919061584d565b6130af57604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613105576040519150601f19603f3d011682016040523d82523d6000602084013e61310a565b606091505b505090508061312c5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4906060016125d0565b6000546001600160a01b03163314612fda5760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610b20565b6040805160a0810182526000606082018181526080830182905282526020820181905291810191909152600061320d84600001516125df565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b0316918301919091529192509061326b57604051631dfd6e1360e21b815260048101839052602401610b20565b60008286608001516040516020016132849291906156b2565b60408051601f1981840301815291815281516020928301206000818152600f90935290822054909250908190036132ce57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d015193516132fd978a979096959101615c1d565b6040516020818303038152906040528051906020012081146133325760405163354a450b60e21b815260040160405180910390fd5b60006133418760000151613bb3565b9050806133f9578651604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d389161339591906004016153a6565b602060405180830381865afa1580156133b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d69190615c04565b9050806133f957865160405163175dadad60e01b8152610b2091906004016153a6565b600088608001518260405160200161341b929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006134428a83613c81565b604080516060810182529788526020880196909652948601949094525092979650505050505050565b6000816001600160401b03163a11156134b157821561349457506001600160401b0381166123f2565b3a8260405163435e532d60e11b8152600401610b20929190615883565b503a92915050565b6000806000631fe543e360e01b86856040516024016134d9929190615c71565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b17905590860151608087015191925061353d9163ffffffff9091169083613cec565b600c805460ff60301b191690559695505050505050565b600080831561357357613568868685613d38565b600091509150613583565b61357e868685613e49565b915091505b94509492505050565b6000818152600660205260409020821561364b5780546001600160601b03600160601b90910481169085168110156135d757604051631e9acf1760e31b815260040160405180910390fd5b6135e18582615692565b8254600160601b600160c01b031916600160601b6001600160601b039283168102919091178455600b805488939192600c9261362192869290041661589a565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050612bd2565b80546001600160601b0390811690851681101561367b57604051631e9acf1760e31b815260040160405180910390fd5b6136858582615692565b82546001600160601b0319166001600160601b03918216178355600b805487926000916136b49185911661589a565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050505050565b601154600090815b8181101561374057836001600160a01b03166011828154811061370c5761370c6156c0565b6000918252602090912001546001600160a01b031603613730575060019392505050565b613739816156d6565b90506136e7565b5060009392505050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b818110156137ec576004600084838154811061379f5761379f6156c0565b60009182526020808320909101546001600160a01b031683528281019390935260409182018120898252909252902080546001600160881b03191690556137e5816156d6565b9050613781565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906138246002830182614e5e565b505060008581526006602052604081205561384060088661403a565b506001600160601b0384161561389357600a805485919060009061386e9084906001600160601b0316615692565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156138eb5782600a600c8282829054906101000a90046001600160601b03166138c69190615692565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f1981840301815290829052805160209182012092506139579189918491016156b2565b60408051808303601f19018152919052805160209091012097909650945050505050565b60408051602081019091526000815260008290036139a857506040805160208101909152600081526123f2565b63125fa26760e31b6139ba8385615c92565b6001600160e01b031916146139e257604051632923fee760e11b815260040160405180910390fd5b6139ef8260048186615cc2565b810190610dfb9190615cec565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613a3591511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b600046613a7981614046565b15613ae75760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae19190615c04565b91505090565b4391505090565b6000610dfb8383614069565b60006123f2825490565b6000610dfb83836140b8565b336001600160a01b03821603613b625760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610b20565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613bbf81614046565b15613c7257610100836001600160401b0316613bd9613a6d565b613be39190615740565b1180613bff5750613bf2613a6d565b836001600160401b031610155b15613c0d5750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613c319086906004016153a6565b602060405180830381865afa158015613c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfb9190615c04565b50506001600160401b03164090565b6000613cb58360000151846020015185604001518660600151868860a001518960c001518a60e001518b61010001516140e2565b60038360200151604051602001613ccd929190615d37565b60408051601f1981840301815291905280516020909101209392505050565b60005a611388811015613cfe57600080fd5b611388810390508460408204820311613d1657600080fd5b50823b613d2257600080fd5b60008083516020850160008789f1949350505050565b600080613d7b6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506142fd92505050565b905060005a600c54613d9b908890600160581b900463ffffffff166158ba565b613da59190615740565b613daf9086615d4b565b600c54909150600090613dd490600160781b900463ffffffff1664e8d4a51000615d4b565b90508415613e2057600c548190606490600160b81b900460ff16613df885876158ba565b613e029190615d4b565b613e0c9190615d78565b613e1691906158ba565b9350505050610dfb565b600c548190606490613e3c90600160b81b900460ff1682615d8c565b60ff16613df885876158ba565b600080600080613e576143d0565b9150915060008213613e7f576040516321ea67b360e11b815260048101839052602401610b20565b6000613ec16000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506142fd92505050565b9050600083825a600c54613ee3908d90600160581b900463ffffffff166158ba565b613eed9190615740565b613ef7908b615d4b565b613f0191906158ba565b613f1390670de0b6b3a7640000615d4b565b613f1d9190615d78565b600c54909150600090613f469063ffffffff600160981b8204811691600160781b900416615da5565b613f5b9063ffffffff1664e8d4a51000615d4b565b9050600085613f7283670de0b6b3a7640000615d4b565b613f7c9190615d78565b905060008915613fbd57600c548290606490613fa290600160c01b900460ff1687615d4b565b613fac9190615d78565b613fb691906158ba565b9050613ffd565b600c548290606490613fd990600160c01b900460ff1682615d8c565b613fe69060ff1687615d4b565b613ff09190615d78565b613ffa91906158ba565b90505b676765c793fa10079d601b1b8111156140295760405163e80fa38160e01b815260040160405180910390fd5b9b949a509398505050505050505050565b6000610dfb8383614497565b600061a4b182148061405a575062066eed82145b806123f257505062066eee1490565b60008181526001830160205260408120546140b0575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556123f2565b5060006123f2565b60008260000182815481106140cf576140cf6156c0565b9060005260206000200154905092915050565b6140eb89614591565b6141345760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610b20565b61413d88614591565b6141815760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610b20565b61418a83614591565b6141d65760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610b20565b6141df82614591565b61422a5760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b6044820152606401610b20565b614236878a8887614654565b61427e5760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610b20565b600061428a8a87614768565b9050600061429d898b878b8689896147cc565b905060006142ae838d8d8a866148eb565b9050808a146142ef5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610b20565b505050505050505050505050565b60004661430981614046565b1561434d57606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c4e573d6000803e3d6000fd5b6143568161492b565b156143c757600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615f186048913960405160200161439c929190615dc2565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613c319190615818565b50600092915050565b600c5460035460408051633fabe5a360e21b815290516000938493600160381b90910463ffffffff169284926001600160a01b039092169163feaf968c9160048082019260a0929091908290030181865afa158015614433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144579190615e08565b50919650909250505063ffffffff821615801590614483575061447a8142615740565b8263ffffffff16105b925082156144915760105493505b50509091565b600081815260018301602052604081205480156145805760006144bb600183615740565b85549091506000906144cf90600190615740565b90508181146145345760008660000182815481106144ef576144ef6156c0565b9060005260206000200154905080876000018481548110614512576145126156c0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061454557614545615aac565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506123f2565b60009150506123f2565b5092915050565b80516000906401000003d019116145df5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610b20565b60208201516401000003d0191161462d5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610b20565b60208201516401000003d01990800961464d8360005b6020020151614965565b1492915050565b60006001600160a01b03821661469a5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610b20565b6020840151600090600116156146b157601c6146b4565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe199182039250600091908909875160408051600080825260209091019182905292935060019161471e91869188918790615e58565b6020604051602081039080840390855afa158015614740573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614770614e7c565b61479d6001848460405160200161478993929190615e76565b604051602081830303815290604052614989565b90505b6147a981614591565b6123f25780516040805160208101929092526147c59101614789565b90506147a0565b6147d4614e7c565b825186516401000003d01991829006919006036148335760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610b20565b61483e8789886149d6565b6148835760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610b20565b61488e8486856149d6565b6148d45760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610b20565b6148df868484614af4565b98975050505050505050565b60006002868686858760405160200161490996959493929190615e97565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a82148061493d57506101a482145b8061494a575062aa37dc82145b80614956575061210582145b806123f257505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614991614e7c565b61499a82614bb7565b81526149af6149aa826000614643565b614bf2565b6020820181905260029006600103611cba576020810180516401000003d019039052919050565b600082600003614a165760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610b20565b83516020850151600090614a2c90600290615ef1565b15614a3857601c614a3b565b601b5b9050600070014551231950b75fc4402da1732fc9bebe19838709604080516000808252602090910191829052919250600190614a7e908390869088908790615e58565b6020604051602081039080840390855afa158015614aa0573d6000803e3d6000fd5b505050602060405103519050600086604051602001614abf9190615f05565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614afc614e7c565b835160208086015185519186015160009384938493614b1d93909190614c12565b919450925090506401000003d019858209600114614b795760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610b20565b60405180604001604052806401000003d01980614b9857614b98615d62565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611cba57604080516020808201939093528151808203840181529082019091528051910120614bbf565b60006123f2826002614c0b6401000003d01960016158ba565b901c614cf2565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614c5283838585614d8c565b9098509050614c6388828e88614db0565b9098509050614c7488828c87614db0565b90985090506000614c878d878b85614db0565b9098509050614c9888828686614d8c565b9098509050614ca988828e89614db0565b9098509050818114614cde576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614ce2565b8196505b5050505050509450945094915050565b600080614cfd614e9a565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614d2f614eb8565b60208160c0846005600019fa925082600003614d825760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610b20565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614e4e579160200282015b82811115614e4e57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614e19565b50614e5a929150614ed6565b5090565b5080546000825590600052602060002090810190612f4b9190614ed6565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614e5a5760008155600101614ed7565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015614f3c57845183529383019391830191600101614f20565b509098975050505050505050565b6001600160a01b0381168114612f4b57600080fd5b8035611cba81614f4a565b60008060408385031215614f7d57600080fd5b823591506020830135614f8f81614f4a565b809150509250929050565b6001600160a01b0391909116815260200190565b600060208284031215614fc057600080fd5b8135610dfb81614f4a565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b038111828210171561500357615003614fcb565b60405290565b60405161012081016001600160401b038111828210171561500357615003614fcb565b604051601f8201601f191681016001600160401b038111828210171561505457615054614fcb565b604052919050565b600082601f83011261506d57600080fd5b604080519081016001600160401b038111828210171561508f5761508f614fcb565b80604052508060408401858111156150a657600080fd5b845b818110156150c05780358352602092830192016150a8565b509195945050505050565b80356001600160401b0381168114611cba57600080fd5b803563ffffffff81168114611cba57600080fd5b600060c0828403121561510857600080fd5b615110614fe1565b905061511b826150cb565b815260208083013581830152615133604084016150e2565b6040830152615144606084016150e2565b6060830152608083013561515781614f4a565b608083015260a08301356001600160401b038082111561517657600080fd5b818501915085601f83011261518a57600080fd5b81358181111561519c5761519c614fcb565b6151ae601f8201601f1916850161502c565b915080825286848285010111156151c457600080fd5b80848401858401376000848284010152508060a085015250505092915050565b8015158114612f4b57600080fd5b8035611cba816151e4565b60008060008385036101e081121561521457600080fd5b6101a08082121561522457600080fd5b61522c615009565b9150615238878761505c565b8252615247876040880161505c565b60208301526080860135604083015260a0860135606083015260c0860135608083015261527660e08701614f5f565b60a083015261010061528a8882890161505c565b60c084015261529d88610140890161505c565b60e0840152610180870135908301529093508401356001600160401b038111156152c657600080fd5b6152d2868287016150f6565b9250506152e26101c085016151f2565b90509250925092565b6000602082840312156152fd57600080fd5b5035919050565b6000806040838503121561531757600080fd5b823561532281614f4a565b91506020830135614f8f81614f4a565b6000806060838503121561534557600080fd5b604083018481111561535657600080fd5b839250615362816150cb565b9150509250929050565b60006020828403121561537e57600080fd5b81356001600160401b0381111561539457600080fd5b820160c08185031215610dfb57600080fd5b6001600160401b0391909116815260200190565b60008083601f8401126153cc57600080fd5b5081356001600160401b038111156153e357600080fd5b6020830191508360208285010111156153fb57600080fd5b9250929050565b6000806000806060858703121561541857600080fd5b843561542381614f4a565b93506020850135925060408501356001600160401b0381111561544557600080fd5b615451878288016153ba565b95989497509550505050565b803561ffff81168114611cba57600080fd5b803560ff81168114611cba57600080fd5b60008060008060008060008060006101208a8c03121561549f57600080fd5b6154a88a61545d565b98506154b660208b016150e2565b97506154c460408b016150e2565b96506154d260608b016150e2565b955060808a013594506154e760a08b016150e2565b93506154f560c08b016150e2565b925061550360e08b0161546f565b91506155126101008b0161546f565b90509295985092959850929598565b6000806040838503121561553457600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b8381101561557357815187529582019590820190600101615557565b509495945050505050565b602081526000610dfb6020830184615543565b6000604082840312156155a357600080fd5b610dfb838361505c565b600080602083850312156155c057600080fd5b82356001600160401b038111156155d657600080fd5b6155e2858286016153ba565b90969095509350505050565b600081518084526020808501945080840160005b838110156155735781516001600160a01b031687529582019590820190600101615602565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a060808201819052600090615671908301846155ee565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6001600160601b0382811682821603908082111561458a5761458a61567c565b918252602082015260400190565b634e487b7160e01b600052603260045260246000fd5b6000600182016156e8576156e861567c565b5060010190565b60006001600160401b038281166002600160401b031981016157135761571361567c565b6001019392505050565b60006001600160401b038216806157365761573661567c565b6000190192915050565b818103818111156123f2576123f261567c565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261579860e08401826155ee565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b60005b838110156157e35781810151838201526020016157cb565b50506000910152565b600081518084526158048160208601602086016157c8565b601f01601f19169290920160200192915050565b602081526000610dfb60208301846157ec565b6001600160a01b039290921682526001600160601b0316602082015260400190565b60006020828403121561585f57600080fd5b8151610dfb816151e4565b6001600160a01b03929092168252602082015260400190565b9182526001600160401b0316602082015260400190565b6001600160601b0381811683821601908082111561458a5761458a61567c565b808201808211156123f2576123f261567c565b9182526001600160a01b0316602082015260400190565b6000602082840312156158f657600080fd5b610dfb8261545d565b61ffff93841681529183166020830152909116604082015260600190565b60006020828403121561592f57600080fd5b610dfb826150e2565b63ffffffff92831681529116602082015260400190565b6000808335601e1984360301811261596657600080fd5b8301803591506001600160401b0382111561598057600080fd5b6020019150368190038213156153fb57600080fd5b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c082018190526000906159e1908301846157ec565b9998505050505050505050565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a08301526148df60c08301846157ec565b6001600160401b0381811683821601908082111561458a5761458a61567c565b60ff92831681529116602082015260400190565b6001600160a01b0392831681529116602082015260400190565b8060005b6002811015612bd2578151845260209384019390910190600101615a7f565b604081016123f28284615a7b565b634e487b7160e01b600052603160045260246000fd5b80356001600160601b0381168114611cba57600080fd5b60006020808385031215615aec57600080fd5b82356001600160401b0380821115615b0357600080fd5b9084019060c08287031215615b1757600080fd5b615b1f614fe1565b615b288361546f565b815283830135848201526040830135615b4081614f4a565b6040820152606083013582811115615b5757600080fd5b8301601f81018813615b6857600080fd5b803583811115615b7a57615b7a614fcb565b8060051b9350615b8b86850161502c565b818152938201860193868101908a861115615ba557600080fd5b928701925b85841015615bcf5783359250615bbf83614f4a565b8282529287019290870190615baa565b606085015250615be491505060808401615ac2565b6080820152615bf560a08401615ac2565b60a08201529695505050505050565b600060208284031215615c1657600080fd5b5051919050565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c082018190526000906159e1908301846157ec565b828152604060208201526000615c8a6040830184615543565b949350505050565b6001600160e01b03198135818116916004851015615cba5780818660040360031b1b83161692505b505092915050565b60008085851115615cd257600080fd5b83861115615cdf57600080fd5b5050820193919092039150565b600060208284031215615cfe57600080fd5b604051602081016001600160401b0381118282101715615d2057615d20614fcb565b6040528235615d2e816151e4565b81529392505050565b82815260608101610dfb6020830184615a7b565b80820281158282048414176123f2576123f261567c565b634e487b7160e01b600052601260045260246000fd5b600082615d8757615d87615d62565b500490565b60ff81811683821601908111156123f2576123f261567c565b63ffffffff82811682821603908082111561458a5761458a61567c565b60008351615dd48184602088016157c8565b835190830190615de88183602088016157c8565b01949350505050565b80516001600160501b0381168114611cba57600080fd5b600080600080600060a08688031215615e2057600080fd5b615e2986615df1565b9450602086015193506040860151925060608601519150615e4c60808701615df1565b90509295509295909350565b93845260ff9290921660208401526040830152606082015260800190565b838152615e866020820184615a7b565b606081019190915260800192915050565b868152615ea76020820187615a7b565b615eb46060820186615a7b565b615ec160a0820185615a7b565b615ece60e0820184615a7b565b60609190911b6001600160601b0319166101208201526101340195945050505050565b600082615f0057615f00615d62565b500690565b615f0f8183615a7b565b60400191905056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a",
}
var VRFCoordinatorV2PlusUpgradedVersionABI = VRFCoordinatorV2PlusUpgradedVersionMetaData.ABI
@@ -559,6 +559,28 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC
return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SCurrentSubNonce(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
}
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_fallbackWeiPerUnitLink")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SFallbackWeiPerUnitLink() (*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SFallbackWeiPerUnitLink() (*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) {
var out []interface{}
err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_provingKeyHashes", arg0)
@@ -581,6 +603,36 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC
return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeyHashes(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
}
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (SProvingKeys,
+
+ error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_provingKeys", arg0)
+
+ outstruct := new(SProvingKeys)
+ if err != nil {
+ return *outstruct, err
+ }
+
+ outstruct.Exists = *abi.ConvertType(out[0], new(bool)).(*bool)
+ outstruct.MaxGas = *abi.ConvertType(out[1], new(uint64)).(*uint64)
+
+ return *outstruct, err
+
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SProvingKeys(arg0 [32]byte) (SProvingKeys,
+
+ error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeys(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SProvingKeys(arg0 [32]byte) (SProvingKeys,
+
+ error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeys(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
+}
+
func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) {
var out []interface{}
err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_requestCommitments", arg0)
@@ -707,16 +759,16 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT
return _VRFCoordinatorV2PlusUpgradedVersion.Contract.CreateSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts)
}
-func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment, arg2 bool) (*types.Transaction, error) {
- return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "fulfillRandomWords", proof, rc, arg2)
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "fulfillRandomWords", proof, rc, onlyPremium)
}
-func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment, arg2 bool) (*types.Transaction, error) {
- return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc, arg2)
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) FulfillRandomWords(proof VRFProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc, onlyPremium)
}
-func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment, arg2 bool) (*types.Transaction, error) {
- return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc, arg2)
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) FulfillRandomWords(proof VRFProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc, onlyPremium)
}
func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) {
@@ -815,16 +867,16 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT
return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, target)
}
-func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) {
- return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "registerProvingKey", publicProvingKey)
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "registerProvingKey", publicProvingKey, maxGas)
}
-func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RegisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) {
- return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, publicProvingKey)
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RegisterProvingKey(publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, publicProvingKey, maxGas)
}
-func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RegisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) {
- return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, publicProvingKey)
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RegisterProvingKey(publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, publicProvingKey, maxGas)
}
func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) {
@@ -984,14 +1036,16 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator) Close() error {
}
type VRFCoordinatorV2PlusUpgradedVersionConfigSet struct {
- MinimumRequestConfirmations uint16
- MaxGasLimit uint32
- StalenessSeconds uint32
- GasAfterPaymentCalculation uint32
- FallbackWeiPerUnitLink *big.Int
- NativePremiumPercentage uint8
- LinkPremiumPercentage uint8
- Raw types.Log
+ MinimumRequestConfirmations uint16
+ MaxGasLimit uint32
+ StalenessSeconds uint32
+ GasAfterPaymentCalculation uint32
+ FallbackWeiPerUnitLink *big.Int
+ FulfillmentFlatFeeNativePPM uint32
+ FulfillmentFlatFeeLinkDiscountPPM uint32
+ NativePremiumPercentage uint8
+ LinkPremiumPercentage uint8
+ Raw types.Log
}
func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator, error) {
@@ -1163,6 +1217,124 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF
return event, nil
}
+type VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed)
+ 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(VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed)
+ 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 *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed struct {
+ RequestId *big.Int
+ FallbackWeiPerUnitLink *big.Int
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterFallbackWeiPerUnitLinkUsed(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "FallbackWeiPerUnitLinkUsed")
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "FallbackWeiPerUnitLinkUsed", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchFallbackWeiPerUnitLinkUsed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) (event.Subscription, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "FallbackWeiPerUnitLinkUsed")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "FallbackWeiPerUnitLinkUsed", 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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseFallbackWeiPerUnitLinkUsed(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "FallbackWeiPerUnitLinkUsed", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
type VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator struct {
Event *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered
@@ -1851,6 +2023,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator) Close
type VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered struct {
KeyHash [32]byte
+ MaxGas uint64
Raw types.Log
}
@@ -1967,46 +2140,48 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator) Close
}
type VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled struct {
- RequestId *big.Int
- OutputSeed *big.Int
- SubID *big.Int
- Payment *big.Int
- Success bool
- Raw types.Log
+ RequestId *big.Int
+ OutputSeed *big.Int
+ SubId *big.Int
+ Payment *big.Int
+ NativePayment bool
+ Success bool
+ OnlyPremium bool
+ Raw types.Log
}
-func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error) {
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error) {
var requestIdRule []interface{}
for _, requestIdItem := range requestId {
requestIdRule = append(requestIdRule, requestIdItem)
}
- var subIDRule []interface{}
- for _, subIDItem := range subID {
- subIDRule = append(subIDRule, subIDItem)
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
}
- logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIDRule)
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule)
if err != nil {
return nil, err
}
return &VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil
}
-func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error) {
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) {
var requestIdRule []interface{}
for _, requestIdItem := range requestId {
requestIdRule = append(requestIdRule, requestIdItem)
}
- var subIDRule []interface{}
- for _, subIDItem := range subID {
- subIDRule = append(subIDRule, subIDItem)
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
}
- logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIDRule)
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule)
if err != nil {
return nil, err
}
@@ -3250,6 +3425,10 @@ type SConfig struct {
NativePremiumPercentage uint8
LinkPremiumPercentage uint8
}
+type SProvingKeys struct {
+ Exists bool
+ MaxGas uint64
+}
func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) ParseLog(log types.Log) (generated.AbigenLog, error) {
switch log.Topics[0] {
@@ -3257,6 +3436,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion)
return _VRFCoordinatorV2PlusUpgradedVersion.ParseConfigSet(log)
case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["CoordinatorRegistered"].ID:
return _VRFCoordinatorV2PlusUpgradedVersion.ParseCoordinatorRegistered(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["FallbackWeiPerUnitLinkUsed"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseFallbackWeiPerUnitLinkUsed(log)
case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["FundsRecovered"].ID:
return _VRFCoordinatorV2PlusUpgradedVersion.ParseFundsRecovered(log)
case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["MigrationCompleted"].ID:
@@ -3296,13 +3477,17 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion)
}
func (VRFCoordinatorV2PlusUpgradedVersionConfigSet) Topic() common.Hash {
- return common.HexToHash("0x95cb2ddab6d2297c29a4861691de69b3969c464aa4a9c44258b101ff02ff375a")
+ return common.HexToHash("0x2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b6")
}
func (VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered) Topic() common.Hash {
return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625")
}
+func (VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) Topic() common.Hash {
+ return common.HexToHash("0x6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a")
+}
+
func (VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) Topic() common.Hash {
return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600")
}
@@ -3324,11 +3509,11 @@ func (VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred) Topic() common.Ha
}
func (VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered) Topic() common.Hash {
- return common.HexToHash("0xc9583fd3afa3d7f16eb0b88d0268e7d05c09bafa4b21e092cbd1320e1bc8089d")
+ return common.HexToHash("0x9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd3")
}
func (VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled) Topic() common.Hash {
- return common.HexToHash("0x49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa7")
+ return common.HexToHash("0xaeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b7")
}
func (VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested) Topic() common.Hash {
@@ -3406,8 +3591,14 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface {
SCurrentSubNonce(opts *bind.CallOpts) (uint64, error)
+ SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error)
+
SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error)
+ SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (SProvingKeys,
+
+ error)
+
SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error)
STotalBalance(opts *bind.CallOpts) (*big.Int, error)
@@ -3424,7 +3615,7 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface {
CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error)
- FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment, arg2 bool) (*types.Transaction, error)
+ FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error)
FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error)
@@ -3442,7 +3633,7 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface {
RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error)
- RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error)
+ RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error)
RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error)
@@ -3472,6 +3663,12 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface {
ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered, error)
+ FilterFallbackWeiPerUnitLinkUsed(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator, error)
+
+ WatchFallbackWeiPerUnitLinkUsed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) (event.Subscription, error)
+
+ ParseFallbackWeiPerUnitLinkUsed(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed, error)
+
FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator, error)
WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) (event.Subscription, error)
@@ -3508,9 +3705,9 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface {
ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered, error)
- FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error)
+ FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error)
- WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error)
+ WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error)
ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error)
diff --git a/core/gethwrappers/generated/vrfv2plus_consumer_example/vrfv2plus_consumer_example.go b/core/gethwrappers/generated/vrfv2plus_consumer_example/vrfv2plus_consumer_example.go
index b0a5ac6c4c1..185734e6d9a 100644
--- a/core/gethwrappers/generated/vrfv2plus_consumer_example/vrfv2plus_consumer_example.go
+++ b/core/gethwrappers/generated/vrfv2plus_consumer_example/vrfv2plus_consumer_example.go
@@ -32,7 +32,7 @@ var (
var VRFV2PlusConsumerExampleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorSet\",\"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\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"createSubscriptionAndFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscriptionAndFundNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"idx\",\"type\":\"uint256\"}],\"name\":\"getRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"randomWord\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_recentRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinatorApiV1\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"setSubId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"topUpSubscriptionNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60806040523480156200001157600080fd5b5060405162001a2f38038062001a2f8339810160408190526200003491620001f3565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf816200012b565b5050506001600160a01b038116620000ea5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b03199081166001600160a01b0393841617909155600580548216948316949094179093556003805490931691161790556200022b565b336001600160a01b03821603620001855760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ee57600080fd5b919050565b600080604083850312156200020757600080fd5b6200021283620001d6565b91506200022260208401620001d6565b90509250929050565b6117f4806200023b6000396000f3fe6080604052600436106101445760003560e01c806380980043116100c0578063b96dbba711610074578063de367c8e11610059578063de367c8e146103c0578063eff27017146103ed578063f2fde38b1461040d57600080fd5b8063b96dbba714610398578063cf62c8ab146103a057600080fd5b80638ea98117116100a55780638ea98117146102c45780639eccacf6146102e4578063a168fa891461031157600080fd5b806380980043146102795780638da5cb5b1461029957600080fd5b806336bfffed11610117578063706da1ca116100fc578063706da1ca146101fc5780637725135b1461021257806379ba50971461026457600080fd5b806336bfffed146101c65780635d7d53e3146101e657600080fd5b80631d2b2afd146101495780631fe543e31461015357806329e5d831146101735780632fa4e442146101a6575b600080fd5b61015161042d565b005b34801561015f57600080fd5b5061015161016e366004611393565b61052b565b34801561017f57600080fd5b5061019361018e366004611435565b6105ac565b6040519081526020015b60405180910390f35b3480156101b257600080fd5b506101516101c1366004611457565b6106e8565b3480156101d257600080fd5b506101516101e13660046114b5565b6107fe565b3480156101f257600080fd5b5061019360045481565b34801561020857600080fd5b5061019360065481565b34801561021e57600080fd5b5060035461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019d565b34801561027057600080fd5b50610151610939565b34801561028557600080fd5b5061015161029436600461154d565b600655565b3480156102a557600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661023f565b3480156102d057600080fd5b506101516102df366004611566565b610a36565b3480156102f057600080fd5b5060025461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561031d57600080fd5b5061036661032c36600461154d565b6007602052600090815260409020805460019091015460ff821691610100900473ffffffffffffffffffffffffffffffffffffffff169083565b60408051931515845273ffffffffffffffffffffffffffffffffffffffff90921660208401529082015260600161019d565b610151610bc0565b3480156103ac57600080fd5b506101516103bb366004611457565b610c26565b3480156103cc57600080fd5b5060055461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103f957600080fd5b506101516104083660046115a3565b610c6d565b34801561041957600080fd5b50610151610428366004611566565b610e49565b60065460000361049e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f742073657400000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6005546006546040517f95b55cfc000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff909116906395b55cfc9034906024015b6000604051808303818588803b15801561051057600080fd5b505af1158015610524573d6000803e3d6000fd5b5050505050565b60025473ffffffffffffffffffffffffffffffffffffffff16331461059e576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610495565b6105a88282610e5d565b5050565b60008281526007602090815260408083208151608081018352815460ff811615158252610100900473ffffffffffffffffffffffffffffffffffffffff16818501526001820154818401526002820180548451818702810187019095528085528695929460608601939092919083018282801561064857602002820191906000526020600020905b815481526020019060010190808311610634575b505050505081525050905080604001516000036106c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610495565b806060015183815181106106d7576106d761160e565b602002602001015191505092915050565b600654600003610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f74207365740000000000000000000000000000000000000000006044820152606401610495565b60035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b81526004016107bb939291906116a1565b6020604051808303816000875af11580156107da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a891906116ed565b60065460000361086a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f7420736574000000000000000000000000000000000000006044820152606401610495565b60005b81518110156105a857600554600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c91908590859081106108b0576108b061160e565b60200260200101516040518363ffffffff1660e01b81526004016108f492919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561090e57600080fd5b505af1158015610922573d6000803e3d6000fd5b5050505080806109319061170a565b91505061086d565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610495565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610a76575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610afa5733610a9b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610495565b73ffffffffffffffffffffffffffffffffffffffff8116610b47576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b610bc8610f28565b506005546006546040517f95b55cfc000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff909116906395b55cfc9034906024016104f7565b610c2e610f28565b5060035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea093169185910161078e565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff168152602001610cc3604051806020016040528086151581525061105d565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610d21908590600401611769565b6020604051808303816000875af1158015610d40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6491906117ce565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff161761010073ffffffffffffffffffffffffffffffffffffffff9094169390930292909217825591516001820155925180519495509193849392610e37926002850192910190611291565b50505060049190915550505050505050565b610e51611119565b610e5a8161119c565b50565b6004548214610ec8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610495565b60008281526007602090815260409091208251610eed92600290920191840190611291565b5050600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600060065460000361105657600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc791906117ce565b60068190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b15801561103d57600080fd5b505af1158015611051573d6000803e3d6000fd5b505050505b5060065490565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161109691511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461119a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610495565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361121b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610495565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8280548282559060005260206000209081019282156112cc579160200282015b828111156112cc5782518255916020019190600101906112b1565b506112d89291506112dc565b5090565b5b808211156112d857600081556001016112dd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611367576113676112f1565b604052919050565b600067ffffffffffffffff821115611389576113896112f1565b5060051b60200190565b600080604083850312156113a657600080fd5b8235915060208084013567ffffffffffffffff8111156113c557600080fd5b8401601f810186136113d657600080fd5b80356113e96113e48261136f565b611320565b81815260059190911b8201830190838101908883111561140857600080fd5b928401925b828410156114265783358252928401929084019061140d565b80955050505050509250929050565b6000806040838503121561144857600080fd5b50508035926020909101359150565b60006020828403121561146957600080fd5b81356bffffffffffffffffffffffff8116811461148557600080fd5b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146114b057600080fd5b919050565b600060208083850312156114c857600080fd5b823567ffffffffffffffff8111156114df57600080fd5b8301601f810185136114f057600080fd5b80356114fe6113e48261136f565b81815260059190911b8201830190838101908783111561151d57600080fd5b928401925b82841015611542576115338461148c565b82529284019290840190611522565b979650505050505050565b60006020828403121561155f57600080fd5b5035919050565b60006020828403121561157857600080fd5b6114858261148c565b803563ffffffff811681146114b057600080fd5b8015158114610e5a57600080fd5b600080600080600060a086880312156115bb57600080fd5b6115c486611581565b9450602086013561ffff811681146115db57600080fd5b93506115e960408701611581565b925060608601359150608086013561160081611595565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815180845260005b8181101561166357602081850181015186830182015201611647565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006116e4606083018461163d565b95945050505050565b6000602082840312156116ff57600080fd5b815161148581611595565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611762577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c0808401526117c660e084018261163d565b949350505050565b6000602082840312156117e057600080fd5b505191905056fea164736f6c6343000813000a",
+ Bin: "0x60806040523480156200001157600080fd5b5060405162001a1d38038062001a1d8339810160408190526200003491620001f3565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf816200012b565b5050506001600160a01b038116620000ea5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b03199081166001600160a01b0393841617909155600580548216948316949094179093556003805490931691161790556200022b565b336001600160a01b03821603620001855760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ee57600080fd5b919050565b600080604083850312156200020757600080fd5b6200021283620001d6565b91506200022260208401620001d6565b90509250929050565b6117e2806200023b6000396000f3fe6080604052600436106101445760003560e01c806380980043116100c0578063b96dbba711610074578063de367c8e11610059578063de367c8e146103c0578063eff27017146103ed578063f2fde38b1461040d57600080fd5b8063b96dbba714610398578063cf62c8ab146103a057600080fd5b80638ea98117116100a55780638ea98117146102c45780639eccacf6146102e4578063a168fa891461031157600080fd5b806380980043146102795780638da5cb5b1461029957600080fd5b806336bfffed11610117578063706da1ca116100fc578063706da1ca146101fc5780637725135b1461021257806379ba50971461026457600080fd5b806336bfffed146101c65780635d7d53e3146101e657600080fd5b80631d2b2afd146101495780631fe543e31461015357806329e5d831146101735780632fa4e442146101a6575b600080fd5b61015161042d565b005b34801561015f57600080fd5b5061015161016e36600461132a565b61052b565b34801561017f57600080fd5b5061019361018e3660046113a9565b6105ae565b6040519081526020015b60405180910390f35b3480156101b257600080fd5b506101516101c13660046113cb565b6106ea565b3480156101d257600080fd5b506101516101e1366004611458565b610804565b3480156101f257600080fd5b5061019360045481565b34801561020857600080fd5b5061019360065481565b34801561021e57600080fd5b5060035461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019d565b34801561027057600080fd5b5061015161093f565b34801561028557600080fd5b5061015161029436600461153b565b600655565b3480156102a557600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661023f565b3480156102d057600080fd5b506101516102df366004611554565b610a3c565b3480156102f057600080fd5b5060025461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561031d57600080fd5b5061036661032c36600461153b565b6007602052600090815260409020805460019091015460ff821691610100900473ffffffffffffffffffffffffffffffffffffffff169083565b60408051931515845273ffffffffffffffffffffffffffffffffffffffff90921660208401529082015260600161019d565b610151610bc6565b3480156103ac57600080fd5b506101516103bb3660046113cb565b610c2c565b3480156103cc57600080fd5b5060055461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103f957600080fd5b50610151610408366004611591565b610c73565b34801561041957600080fd5b50610151610428366004611554565b610e4f565b60065460000361049e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f742073657400000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6005546006546040517f95b55cfc000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff909116906395b55cfc9034906024015b6000604051808303818588803b15801561051057600080fd5b505af1158015610524573d6000803e3d6000fd5b5050505050565b60025473ffffffffffffffffffffffffffffffffffffffff16331461059e576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610495565b6105a9838383610e63565b505050565b60008281526007602090815260408083208151608081018352815460ff811615158252610100900473ffffffffffffffffffffffffffffffffffffffff16818501526001820154818401526002820180548451818702810187019095528085528695929460608601939092919083018282801561064a57602002820191906000526020600020905b815481526020019060010190808311610636575b505050505081525050905080604001516000036106c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610495565b806060015183815181106106d9576106d96115fc565b602002602001015191505092915050565b600654600003610756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f74207365740000000000000000000000000000000000000000006044820152606401610495565b60035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b81526004016107bd9392919061168f565b6020604051808303816000875af11580156107dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080091906116db565b5050565b600654600003610870576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f7420736574000000000000000000000000000000000000006044820152606401610495565b60005b815181101561080057600554600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c91908590859081106108b6576108b66115fc565b60200260200101516040518363ffffffff1660e01b81526004016108fa92919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561091457600080fd5b505af1158015610928573d6000803e3d6000fd5b505050508080610937906116f8565b915050610873565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610495565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610a7c575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610b005733610aa160005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610495565b73ffffffffffffffffffffffffffffffffffffffff8116610b4d576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b610bce610f26565b506005546006546040517f95b55cfc000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff909116906395b55cfc9034906024016104f7565b610c34610f26565b5060035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0931691859101610790565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff168152602001610cc9604051806020016040528086151581525061105b565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610d27908590600401611757565b6020604051808303816000875af1158015610d46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6a91906117bc565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff161761010073ffffffffffffffffffffffffffffffffffffffff9094169390930292909217825591516001820155925180519495509193849392610e3d92600285019291019061128f565b50505060049190915550505050505050565b610e57611117565b610e608161119a565b50565b6004548314610ece576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610495565b6000838152600760205260409020610eea9060020183836112da565b505050600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600060065460000361105457600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610fa1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc591906117bc565b60068190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b15801561103b57600080fd5b505af115801561104f573d6000803e3d6000fd5b505050505b5060065490565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161109491511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611198576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610495565b565b3373ffffffffffffffffffffffffffffffffffffffff821603611219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610495565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8280548282559060005260206000209081019282156112ca579160200282015b828111156112ca5782518255916020019190600101906112af565b506112d6929150611315565b5090565b8280548282559060005260206000209081019282156112ca579160200282015b828111156112ca5782358255916020019190600101906112fa565b5b808211156112d65760008155600101611316565b60008060006040848603121561133f57600080fd5b83359250602084013567ffffffffffffffff8082111561135e57600080fd5b818601915086601f83011261137257600080fd5b81358181111561138157600080fd5b8760208260051b850101111561139657600080fd5b6020830194508093505050509250925092565b600080604083850312156113bc57600080fd5b50508035926020909101359150565b6000602082840312156113dd57600080fd5b81356bffffffffffffffffffffffff811681146113f957600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461145357600080fd5b919050565b6000602080838503121561146b57600080fd5b823567ffffffffffffffff8082111561148357600080fd5b818501915085601f83011261149757600080fd5b8135818111156114a9576114a9611400565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811085821117156114ec576114ec611400565b60405291825284820192508381018501918883111561150a57600080fd5b938501935b8285101561152f576115208561142f565b8452938501939285019261150f565b98975050505050505050565b60006020828403121561154d57600080fd5b5035919050565b60006020828403121561156657600080fd5b6113f98261142f565b803563ffffffff8116811461145357600080fd5b8015158114610e6057600080fd5b600080600080600060a086880312156115a957600080fd5b6115b28661156f565b9450602086013561ffff811681146115c957600080fd5b93506115d76040870161156f565b92506060860135915060808601356115ee81611583565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815180845260005b8181101561165157602081850181015186830182015201611635565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006116d2606083018461162b565b95945050505050565b6000602082840312156116ed57600080fd5b81516113f981611583565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611750577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c0808401526117b460e084018261162b565b949350505050565b6000602082840312156117ce57600080fd5b505191905056fea164736f6c6343000813000a",
}
var VRFV2PlusConsumerExampleABI = VRFV2PlusConsumerExampleMetaData.ABI
diff --git a/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go b/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go
index 73b85e12f80..915becd28d7 100644
--- a/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go
+++ b/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go
@@ -32,7 +32,7 @@ var (
var VRFV2PlusRevertingExampleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorSet\",\"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\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"createSubscriptionAndFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"minReqConfs\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"}],\"name\":\"requestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60806040523480156200001157600080fd5b506040516200127d3803806200127d8339810160408190526200003491620001e8565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000120565b5050506001600160a01b038116620000ea5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039283166001600160a01b031991821617909155600580549390921692169190911790555062000220565b336001600160a01b038216036200017a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001e357600080fd5b919050565b60008060408385031215620001fc57600080fd5b6200020783620001cb565b91506200021760208401620001cb565b90509250929050565b61104d80620002306000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638ea981171161008c578063e89e106a11610066578063e89e106a146101e6578063f08c5daa146101ef578063f2fde38b146101f8578063f6eaffc81461020b57600080fd5b80638ea98117146101a05780639eccacf6146101b3578063cf62c8ab146101d357600080fd5b806336bfffed116100c857806336bfffed1461013d578063706da1ca1461015057806379ba5097146101595780638da5cb5b1461016157600080fd5b80631fe543e3146100ef5780632e75964e146101045780632fa4e4421461012a575b600080fd5b6101026100fd366004610c22565b61021e565b005b610117610112366004610cdd565b6102a2565b6040519081526020015b60405180910390f35b610102610138366004610d3d565b610390565b61010261014b366004610d96565b6104a6565b61011760065481565b6101026105e1565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b6101026101ae366004610e2e565b6106de565b60025461017b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101026101e1366004610d3d565b610868565b61011760045481565b61011760075481565b610102610206366004610e2e565b6109d3565b610117610219366004610e49565b6109e7565b60025473ffffffffffffffffffffffffffffffffffffffff163314610296576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61029e600080fd5b5050565b6040805160c081018252868152602080820187905261ffff86168284015263ffffffff80861660608401528416608083015282519081018352600080825260a083019190915260025492517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff1690639b1c385e9061033d908490600401610ec6565b6020604051808303816000875af115801561035c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103809190610f2b565b6004819055979650505050505050565b6006546000036103fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f7420736574000000000000000000000000000000000000000000604482015260640161028d565b60055460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b815260040161046393929190610f44565b6020604051808303816000875af1158015610482573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029e9190610f90565b600654600003610512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161028d565b60005b815181101561029e57600254600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061055857610558610fb2565b60200260200101516040518363ffffffff1660e01b815260040161059c92919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156105b657600080fd5b505af11580156105ca573d6000803e3d6000fd5b5050505080806105d990610fe1565b915050610515565b60015473ffffffffffffffffffffffffffffffffffffffff163314610662576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161028d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061071e575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156107a2573361074360005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161028d565b73ffffffffffffffffffffffffffffffffffffffff81166107ef576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b6006546000036103fc57600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af11580156108e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109059190610f2b565b60068190556002546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b15801561097b57600080fd5b505af115801561098f573d6000803e3d6000fd5b5050505060055460025460065460405173ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591610436919060200190815260200190565b6109db610a08565b6109e481610a8b565b50565b600381815481106109f757600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161028d565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610b0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161028d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610bf657610bf6610b80565b604052919050565b600067ffffffffffffffff821115610c1857610c18610b80565b5060051b60200190565b60008060408385031215610c3557600080fd5b8235915060208084013567ffffffffffffffff811115610c5457600080fd5b8401601f81018613610c6557600080fd5b8035610c78610c7382610bfe565b610baf565b81815260059190911b82018301908381019088831115610c9757600080fd5b928401925b82841015610cb557833582529284019290840190610c9c565b80955050505050509250929050565b803563ffffffff81168114610cd857600080fd5b919050565b600080600080600060a08688031215610cf557600080fd5b8535945060208601359350604086013561ffff81168114610d1557600080fd5b9250610d2360608701610cc4565b9150610d3160808701610cc4565b90509295509295909350565b600060208284031215610d4f57600080fd5b81356bffffffffffffffffffffffff81168114610d6b57600080fd5b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610cd857600080fd5b60006020808385031215610da957600080fd5b823567ffffffffffffffff811115610dc057600080fd5b8301601f81018513610dd157600080fd5b8035610ddf610c7382610bfe565b81815260059190911b82018301908381019087831115610dfe57600080fd5b928401925b82841015610e2357610e1484610d72565b82529284019290840190610e03565b979650505050505050565b600060208284031215610e4057600080fd5b610d6b82610d72565b600060208284031215610e5b57600080fd5b5035919050565b6000815180845260005b81811015610e8857602081850181015186830182015201610e6c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610f2360e0840182610e62565b949350505050565b600060208284031215610f3d57600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000610f876060830184610e62565b95945050505050565b600060208284031215610fa257600080fd5b81518015158114610d6b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611039577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c6343000813000a",
+ Bin: "0x60806040523480156200001157600080fd5b5060405162001237380380620012378339810160408190526200003491620001e8565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000120565b5050506001600160a01b038116620000ea5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039283166001600160a01b031991821617909155600580549390921692169190911790555062000220565b336001600160a01b038216036200017a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001e357600080fd5b919050565b60008060408385031215620001fc57600080fd5b6200020783620001cb565b91506200021760208401620001cb565b90509250929050565b61100780620002306000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638ea981171161008c578063e89e106a11610066578063e89e106a146101e6578063f08c5daa146101ef578063f2fde38b146101f8578063f6eaffc81461020b57600080fd5b80638ea98117146101a05780639eccacf6146101b3578063cf62c8ab146101d357600080fd5b806336bfffed116100c857806336bfffed1461013d578063706da1ca1461015057806379ba5097146101595780638da5cb5b1461016157600080fd5b80631fe543e3146100ef5780632e75964e146101045780632fa4e4421461012a575b600080fd5b6101026100fd366004610b85565b61021e565b005b610117610112366004610c1d565b6102a3565b6040519081526020015b60405180910390f35b610102610138366004610c7d565b610391565b61010261014b366004610d05565b6104ab565b61011760065481565b6101026105e6565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b6101026101ae366004610de8565b6106e3565b60025461017b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101026101e1366004610c7d565b61086d565b61011760045481565b61011760075481565b610102610206366004610de8565b6109d8565b610117610219366004610e03565b6109ec565b60025473ffffffffffffffffffffffffffffffffffffffff163314610296576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61029e600080fd5b505050565b6040805160c081018252868152602080820187905261ffff86168284015263ffffffff80861660608401528416608083015282519081018352600080825260a083019190915260025492517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff1690639b1c385e9061033e908490600401610e80565b6020604051808303816000875af115801561035d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103819190610ee5565b6004819055979650505050505050565b6006546000036103fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f7420736574000000000000000000000000000000000000000000604482015260640161028d565b60055460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b815260040161046493929190610efe565b6020604051808303816000875af1158015610483573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a79190610f4a565b5050565b600654600003610517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161028d565b60005b81518110156104a757600254600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061055d5761055d610f6c565b60200260200101516040518363ffffffff1660e01b81526004016105a192919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156105bb57600080fd5b505af11580156105cf573d6000803e3d6000fd5b5050505080806105de90610f9b565b91505061051a565b60015473ffffffffffffffffffffffffffffffffffffffff163314610667576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161028d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610723575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156107a7573361074860005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161028d565b73ffffffffffffffffffffffffffffffffffffffff81166107f4576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be69060200160405180910390a150565b6006546000036103fd57600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af11580156108e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090a9190610ee5565b60068190556002546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b15801561098057600080fd5b505af1158015610994573d6000803e3d6000fd5b5050505060055460025460065460405173ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591610437919060200190815260200190565b6109e0610a0d565b6109e981610a90565b50565b600381815481106109fc57600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161028d565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610b0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161028d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080600060408486031215610b9a57600080fd5b83359250602084013567ffffffffffffffff80821115610bb957600080fd5b818601915086601f830112610bcd57600080fd5b813581811115610bdc57600080fd5b8760208260051b8501011115610bf157600080fd5b6020830194508093505050509250925092565b803563ffffffff81168114610c1857600080fd5b919050565b600080600080600060a08688031215610c3557600080fd5b8535945060208601359350604086013561ffff81168114610c5557600080fd5b9250610c6360608701610c04565b9150610c7160808701610c04565b90509295509295909350565b600060208284031215610c8f57600080fd5b81356bffffffffffffffffffffffff81168114610cab57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610c1857600080fd5b60006020808385031215610d1857600080fd5b823567ffffffffffffffff80821115610d3057600080fd5b818501915085601f830112610d4457600080fd5b813581811115610d5657610d56610cb2565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610d9957610d99610cb2565b604052918252848201925083810185019188831115610db757600080fd5b938501935b82851015610ddc57610dcd85610ce1565b84529385019392850192610dbc565b98975050505050505050565b600060208284031215610dfa57600080fd5b610cab82610ce1565b600060208284031215610e1557600080fd5b5035919050565b6000815180845260005b81811015610e4257602081850181015186830182015201610e26565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610edd60e0840182610e1c565b949350505050565b600060208284031215610ef757600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000610f416060830184610e1c565b95945050505050565b600060208284031215610f5c57600080fd5b81518015158114610cab57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ff3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea164736f6c6343000813000a",
}
var VRFV2PlusRevertingExampleABI = VRFV2PlusRevertingExampleMetaData.ABI
diff --git a/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go b/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go
index 7d358d5b03b..897e4550adc 100644
--- a/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go
+++ b/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go
@@ -31,8 +31,8 @@ var (
)
var VRFV2PlusWrapperMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coordinator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"expectedMinimumLength\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"actualLength\",\"type\":\"uint16\"}],\"name\":\"IncorrectExtraArgsLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"max\",\"type\":\"uint8\"}],\"name\":\"InvalidPremiumPercentage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LINKPaymentInRequestRandomWordsInNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativePaymentInOnTokenTransfer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIdMissing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"coordinatorNativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"coordinatorLinkPremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Disabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Enabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"}],\"name\":\"FallbackWeiPerUnitLinkUsed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"FulfillmentTxSizeSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeWithdrawn\",\"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\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"WrapperFulfillmentFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUBSCRIPTION_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"isLinkMode\",\"type\":\"bool\"}],\"name\":\"checkPaymentMode\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"wrapperNativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"wrapperLinkPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"link\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNativeFeed\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"requestRandomWordsInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_callbacks\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"requestGasPrice\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_configured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_disabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fulfillmentTxSizeBytes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"_coordinatorNativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"_coordinatorLinkPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"_maxNumWords\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"_stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"_fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"_fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"setFulfillmentTxSize\",\"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\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60e06040526006805463ffffffff60401b191669024400000000000000001790553480156200002d57600080fd5b5060405162003c1c38038062003c1c8339810160408190526200005091620002a1565b813380600081620000a85760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000db57620000db81620001d9565b5050506001600160a01b038116620001065760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392831617905584811660a052831660c0526000819003620001505760405163a81c0bef60e01b815260040160405180910390fd5b60025460405163dc311dd360e01b8152600481018390526001600160a01b039091169063dc311dd390602401600060405180830381865afa1580156200019a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001c4919081019062000321565b505050608092909252506200044a9350505050565b336001600160a01b03821603620002335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200029c57600080fd5b919050565b60008060008060808587031215620002b857600080fd5b620002c38562000284565b9350620002d36020860162000284565b9250620002e36040860162000284565b6060959095015193969295505050565b80516001600160601b03811681146200029c57600080fd5b634e487b7160e01b600052604160045260246000fd5b600080600080600060a086880312156200033a57600080fd5b6200034586620002f3565b9450602062000356818801620002f3565b60408801519095506001600160401b0380821682146200037557600080fd5b8195506200038660608a0162000284565b945060808901519150808211156200039d57600080fd5b818901915089601f830112620003b257600080fd5b815181811115620003c757620003c76200030b565b8060051b604051601f19603f83011681018181108582111715620003ef57620003ef6200030b565b60405291825284820192508381018501918c8311156200040e57600080fd5b938501935b828510156200043757620004278562000284565b8452938501939285019262000413565b8096505050505050509295509295909350565b60805160a05160c051613778620004a4600039600081816102ff015261260601526000818161028b01528181610f1b01528181610fea0152611ac60152600081816101d90152818161171b0152611cb201526137786000f3fe6080604052600436106101c25760003560e01c806379ba5097116100f7578063a4c0ed3611610095578063cdd8d88511610064578063cdd8d88514610738578063f2fde38b14610776578063fc2a88c314610796578063fc2dbebc146107ac57600080fd5b8063a4c0ed36146105ba578063a608a1e1146105da578063bf17e5591461060d578063c3f909d41461062d57600080fd5b80638ea98117116100d15780638ea98117146105455780639cfc058e146105655780639eccacf614610578578063a3907d71146105a557600080fd5b806379ba5097146104e55780637fb5d19d146104fa5780638da5cb5b1461051a57600080fd5b80632f622e6b1161016457806348baa1c51161013e57806348baa1c5146103985780634b1609351461046357806351cff8d91461048357806357a8070a146104a357600080fd5b80632f622e6b146103385780633255c456146103585780634306d3541461037857600080fd5b80631c4695f4116101a05780631c4695f41461027c5780631fe543e3146102d05780632808e6c8146102f05780632f2770db1461032357600080fd5b8063030932bb146101c7578063181f5a771461020e57806318b6f4c81461025a575b600080fd5b3480156101d357600080fd5b506101fb7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561021a57600080fd5b50604080518082018252601681527f5652465632506c75735772617070657220312e302e3000000000000000000000602082015290516102059190612e0f565b34801561026657600080fd5b5061027a610275366004612f3c565b6107cc565b005b34801561028857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610205565b3480156102dc57600080fd5b5061027a6102eb366004612f8e565b610954565b3480156102fc57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102ab565b34801561032f57600080fd5b5061027a6109d1565b34801561034457600080fd5b5061027a610353366004613064565b610a44565b34801561036457600080fd5b506101fb610373366004613093565b610b6b565b34801561038457600080fd5b506101fb6103933660046130bd565b610c91565b3480156103a457600080fd5b506104226103b33660046130d8565b60076020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000810463ffffffff16907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1683565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff909216602084015267ffffffffffffffff1690820152606001610205565b34801561046f57600080fd5b506101fb61047e3660046130bd565b610dc5565b34801561048f57600080fd5b5061027a61049e366004613064565b610ee2565b3480156104af57600080fd5b506002546104d59074010000000000000000000000000000000000000000900460ff1681565b6040519015158152602001610205565b3480156104f157600080fd5b5061027a6110e3565b34801561050657600080fd5b506101fb610515366004613093565b6111e0565b34801561052657600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166102ab565b34801561055157600080fd5b5061027a610560366004613064565b611313565b6101fb61057336600461314c565b61149e565b34801561058457600080fd5b506002546102ab9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105b157600080fd5b5061027a611949565b3480156105c657600080fd5b5061027a6105d53660046131c2565b6119a4565b3480156105e657600080fd5b506002546104d5907501000000000000000000000000000000000000000000900460ff1681565b34801561061957600080fd5b5061027a6106283660046130bd565b611f11565b34801561063957600080fd5b506005546006546003546002546040805194855263ffffffff80851660208701527001000000000000000000000000000000008504811691860191909152740100000000000000000000000000000000000000008404811660608601526401000000008404811660808601526c0100000000000000000000000084041660a085015260ff78010000000000000000000000000000000000000000000000008404811660c0860152790100000000000000000000000000000000000000000000000000909304831660e085015261010084019190915276010000000000000000000000000000000000000000000090041661012082015261014001610205565b34801561074457600080fd5b506006546107619068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610205565b34801561078257600080fd5b5061027a610791366004613064565b611f8a565b3480156107a257600080fd5b506101fb60045481565b3480156107b857600080fd5b5061027a6107c736600461322d565b611f9e565b8151600003610810578061080c576040517f6b81746e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b81516024111561086a5781516040517f51200dce0000000000000000000000000000000000000000000000000000000081526108619160249160040161ffff92831681529116602082015260400190565b60405180910390fd5b60008260238151811061087f5761087f6132d9565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f01000000000000000000000000000000000000000000000000000000000000001490508080156108d55750815b1561090c576040517f6048aa6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80158015610918575081155b1561094f576040517f6b81746e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146109c7576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610861565b61080c828261226f565b6109d9612452565b600280547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790556040517f75884cdadc4a89e8b545db800057f06ec7f5338a08183c7ba515f2bfdd9fe1e190600090a1565b610a4c612452565b604051479060009073ffffffffffffffffffffffffffffffffffffffff84169083908381818185875af1925050503d8060008114610aa6576040519150601f19603f3d011682016040523d82523d6000602084013e610aab565b606091505b5050905080610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6661696c656420746f207769746864726177206e6174697665000000000000006044820152606401610861565b8273ffffffffffffffffffffffffffffffffffffffff167fc303ca808382409472acbbf899c316cf439f409f6584aae22df86dfa3c9ed50483604051610b5e91815260200190565b60405180910390a2505050565b60025460009074010000000000000000000000000000000000000000900460ff16610bf2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610861565b6002547501000000000000000000000000000000000000000000900460ff1615610c78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610861565b610c888363ffffffff16836124d5565b90505b92915050565b60025460009074010000000000000000000000000000000000000000900460ff16610d18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610861565b6002547501000000000000000000000000000000000000000000900460ff1615610d9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610861565b6000610da86125e8565b509050610dbc8363ffffffff163a8361273e565b9150505b919050565b60025460009074010000000000000000000000000000000000000000900460ff16610e4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610861565b6002547501000000000000000000000000000000000000000000900460ff1615610ed2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610861565b610c8b8263ffffffff163a6124d5565b610eea612452565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610f77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9b9190613308565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110599190613321565b61108f576040517f7c07fc4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5826040516110d791815260200190565b60405180910390a25050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610861565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60025460009074010000000000000000000000000000000000000000900460ff16611267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610861565b6002547501000000000000000000000000000000000000000000900460ff16156112ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610861565b60006112f76125e8565b50905061130b8463ffffffff16848361273e565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611353575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156113d7573361137860005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610861565b73ffffffffffffffffffffffffffffffffffffffff8116611424576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be6906020015b60405180910390a150565b60025460009074010000000000000000000000000000000000000000900460ff16611525576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610861565b6002547501000000000000000000000000000000000000000000900460ff16156115ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610861565b6115ea83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506107cc915050565b60006115f58761289a565b905060006116098863ffffffff163a6124d5565b905080341015611675576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610861565b600254760100000000000000000000000000000000000000000000900460ff1663ffffffff87161115611704576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610861565b60006040518060c0016040528060035481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018961ffff168152602001600660049054906101000a900463ffffffff16858c6117689190613374565b6117729190613374565b63ffffffff1681526020018863ffffffff16815260200187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509152506002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90611818908490600401613398565b6020604051808303816000875af1158015611837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185b9190613308565b6040805160608101825233815263ffffffff808d16602080840191825267ffffffffffffffff3a81168587019081526000888152600790935295909120935184549251955190911678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff9590931674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff91909116171792909216919091179055935050505095945050505050565b611951612452565b600280547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690556040517fc0f961051f97b04c496472d11cb6170d844e4b2c9dfd3b602a4fa0139712d48490600090a1565b60025474010000000000000000000000000000000000000000900460ff16611a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610861565b6002547501000000000000000000000000000000000000000000900460ff1615611aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610861565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611b4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b0000000000000000006044820152606401610861565b6000808080611b5e858701876133f5565b9350935093509350611b718160016107cc565b6000611b7c8561289a565b9050600080611b896125e8565b915091506000611ba08863ffffffff163a8561273e565b9050808b1015611c0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610861565b600254760100000000000000000000000000000000000000000000900460ff1663ffffffff87161115611c9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610861565b60006040518060c0016040528060035481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018961ffff168152602001600660049054906101000a900463ffffffff16878c611cff9190613374565b611d099190613374565b63ffffffff908116825289166020820152604090810188905260025490517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90611d7d908590600401613398565b6020604051808303816000875af1158015611d9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc09190613308565b905060405180606001604052808f73ffffffffffffffffffffffffffffffffffffffff1681526020018b63ffffffff1681526020013a67ffffffffffffffff168152506007600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905050806004819055508315611f01576005546040805183815260208101929092527f6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a910160405180910390a15b5050505050505050505050505050565b611f19612452565b600680547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff8416908102919091179091556040519081527f697b48b8b76cebb09a54ec4ff810e8a181c96f65395d51c744db09c115d1d5d090602001611493565b611f92612452565b611f9b816128b2565b50565b611fa6612452565b8163ffffffff168163ffffffff161115611ffc576040517f2780dcb200000000000000000000000000000000000000000000000000000000815263ffffffff808316600483015283166024820152604401610861565b609b60ff89161115612046576040517f3acc511a00000000000000000000000000000000000000000000000000000000815260ff89166004820152609b6024820152604401610861565b609b60ff88161115612090576040517f3acc511a00000000000000000000000000000000000000000000000000000000815260ff88166004820152609b6024820152604401610861565b89600660046101000a81548163ffffffff021916908363ffffffff160217905550886006600c6101000a81548163ffffffff021916908363ffffffff16021790555087600660186101000a81548160ff021916908360ff16021790555086600660196101000a81548160ff021916908360ff1602179055508560038190555084600260166101000a81548160ff021916908360ff1602179055506001600260146101000a81548160ff02191690831515021790555083600660006101000a81548163ffffffff021916908363ffffffff1602179055508260058190555081600660106101000a81548163ffffffff021916908363ffffffff16021790555080600660146101000a81548163ffffffff021916908363ffffffff1602179055507fb18fd84519589131d50ae195b0aea1b042c3c0b25a53bb894d9d81c78980c20f8a8a8a8a8a8a8a8a8a600660149054906101000a900463ffffffff1660405161225b9a9998979695949392919063ffffffff9a8b168152988a1660208a015260ff97881660408a0152958716606089015260808801949094529190941660a086015292851660c085015260e08401929092529083166101008301529091166101208201526101400190565b60405180910390a150505050505050505050565b60008281526007602081815260408084208151606081018352815473ffffffffffffffffffffffffffffffffffffffff808216835274010000000000000000000000000000000000000000820463ffffffff1683870152780100000000000000000000000000000000000000000000000090910467ffffffffffffffff16938201939093528786529390925292905580519091811661236a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610861565b600080631fe543e360e01b8686604051602401612388929190613464565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060006123fe856020015163ffffffff1685846129a7565b9050806124495760405173ffffffffffffffffffffffffffffffffffffffff85169088907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146124d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610861565b565b60065460009081906124f590640100000000900463ffffffff16846134b2565b6006549091506000906125199068010000000000000000900463ffffffff166129f3565b60065461253c906c01000000000000000000000000900463ffffffff16876134c9565b61254690866134b2565b61255091906134c9565b60065490915060009061258290700100000000000000000000000000000000900463ffffffff1664e8d4a510006134b2565b6006546064906125b1907801000000000000000000000000000000000000000000000000900460ff16826134dc565b6125be9060ff16856134b2565b6125c89190613524565b6125d291906134c9565b90506125de81846134c9565b9695505050505050565b6000806000600660009054906101000a900463ffffffff16905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561266f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126939190613552565b50919650909250505063ffffffff8216158015906126bf57506126b681426135a2565b8263ffffffff16105b925082156126cd5760055493505b6000841215612738576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b20776569207072696365000000000000000000006044820152606401610861565b50509091565b600654600090819061275e90640100000000900463ffffffff16856134b2565b6006549091506000906127829068010000000000000000900463ffffffff166129f3565b6006546127a5906c01000000000000000000000000900463ffffffff16886134c9565b6127af90876134b2565b6127b991906134c9565b6006549091506000906128009063ffffffff7401000000000000000000000000000000000000000082048116917001000000000000000000000000000000009004166135b5565b6128159063ffffffff1664e8d4a510006134b2565b60065460649061284590790100000000000000000000000000000000000000000000000000900460ff16826134dc565b6128529060ff16856134b2565b61285c9190613524565b61286691906134c9565b90508461287382856134c9565b61288590670de0b6b3a76400006134b2565b61288f9190613524565b979650505050505050565b60006128a7603f836135d2565b610c8b906001613374565b3373ffffffffffffffffffffffffffffffffffffffff821603612931576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610861565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a6113888110156129b957600080fd5b6113888103905084604082048203116129d157600080fd5b50823b6129dd57600080fd5b60008083516020850160008789f1949350505050565b6000466129ff81612ab4565b15612a94576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa158015612a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7691906135f5565b5050505091505083608c612a8a91906134c9565b61130b90826134b2565b612a9d81612ad7565b15612aab57610dbc83612b11565b50600092915050565b600061a4b1821480612ac8575062066eed82145b80610c8b57505062066eee1490565b6000600a821480612ae957506101a482145b80612af6575062aa37dc82145b80612b02575061210582145b80610c8b57505062014a331490565b60008073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663519b4bd36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b979190613308565b9050600080612ba681866135a2565b90506000612bb58260106134b2565b612bc08460046134b2565b612bca91906134c9565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff16630c18c1626040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c519190613308565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663f45e65d86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd89190613308565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5f9190613308565b90506000612d6e82600a61375f565b905060008184612d7e87896134c9565b612d88908c6134b2565b612d9291906134b2565b612d9c9190613524565b9b9a5050505050505050505050565b6000815180845260005b81811015612dd157602081850181015186830182015201612db5565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610c886020830184612dab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612e9857612e98612e22565b604052919050565b600082601f830112612eb157600080fd5b813567ffffffffffffffff811115612ecb57612ecb612e22565b612efc60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612e51565b818152846020838601011115612f1157600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114611f9b57600080fd5b60008060408385031215612f4f57600080fd5b823567ffffffffffffffff811115612f6657600080fd5b612f7285828601612ea0565b9250506020830135612f8381612f2e565b809150509250929050565b60008060408385031215612fa157600080fd5b8235915060208084013567ffffffffffffffff80821115612fc157600080fd5b818601915086601f830112612fd557600080fd5b813581811115612fe757612fe7612e22565b8060051b9150612ff8848301612e51565b818152918301840191848101908984111561301257600080fd5b938501935b8385101561303057843582529385019390850190613017565b8096505050505050509250929050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610dc057600080fd5b60006020828403121561307657600080fd5b610c8882613040565b803563ffffffff81168114610dc057600080fd5b600080604083850312156130a657600080fd5b6130af8361307f565b946020939093013593505050565b6000602082840312156130cf57600080fd5b610c888261307f565b6000602082840312156130ea57600080fd5b5035919050565b803561ffff81168114610dc057600080fd5b60008083601f84011261311557600080fd5b50813567ffffffffffffffff81111561312d57600080fd5b60208301915083602082850101111561314557600080fd5b9250929050565b60008060008060006080868803121561316457600080fd5b61316d8661307f565b945061317b602087016130f1565b93506131896040870161307f565b9250606086013567ffffffffffffffff8111156131a557600080fd5b6131b188828901613103565b969995985093965092949392505050565b600080600080606085870312156131d857600080fd5b6131e185613040565b935060208501359250604085013567ffffffffffffffff81111561320457600080fd5b61321087828801613103565b95989497509550505050565b803560ff81168114610dc057600080fd5b6000806000806000806000806000806101408b8d03121561324d57600080fd5b6132568b61307f565b995061326460208c0161307f565b985061327260408c0161321c565b975061328060608c0161321c565b965060808b0135955061329560a08c0161321c565b94506132a360c08c0161307f565b935060e08b013592506132b96101008c0161307f565b91506132c86101208c0161307f565b90509295989b9194979a5092959850565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561331a57600080fd5b5051919050565b60006020828403121561333357600080fd5b815161333e81612f2e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff81811683821601908082111561339157613391613345565b5092915050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261130b60e0840182612dab565b6000806000806080858703121561340b57600080fd5b6134148561307f565b9350613422602086016130f1565b92506134306040860161307f565b9150606085013567ffffffffffffffff81111561344c57600080fd5b61345887828801612ea0565b91505092959194509250565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156134a557845183529383019391830191600101613489565b5090979650505050505050565b8082028115828204841417610c8b57610c8b613345565b80820180821115610c8b57610c8b613345565b60ff8181168382160190811115610c8b57610c8b613345565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613533576135336134f5565b500490565b805169ffffffffffffffffffff81168114610dc057600080fd5b600080600080600060a0868803121561356a57600080fd5b61357386613538565b945060208601519350604086015192506060860151915061359660808701613538565b90509295509295909350565b81810381811115610c8b57610c8b613345565b63ffffffff82811682821603908082111561339157613391613345565b600063ffffffff808416806135e9576135e96134f5565b92169190910492915050565b60008060008060008060c0878903121561360e57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600181815b8085111561369857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561367e5761367e613345565b8085161561368b57918102915b93841c9390800290613644565b509250929050565b6000826136af57506001610c8b565b816136bc57506000610c8b565b81600181146136d257600281146136dc576136f8565b6001915050610c8b565b60ff8411156136ed576136ed613345565b50506001821b610c8b565b5060208310610133831016604e8410600b841016171561371b575081810a610c8b565b613725838361363f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561375757613757613345565b029392505050565b6000610c8883836136a056fea164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coordinator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"expectedMinimumLength\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"actualLength\",\"type\":\"uint16\"}],\"name\":\"IncorrectExtraArgsLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"max\",\"type\":\"uint8\"}],\"name\":\"InvalidPremiumPercentage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LINKPaymentInRequestRandomWordsInNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativePaymentInOnTokenTransfer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIdMissing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"coordinatorGasOverheadPerWord\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"coordinatorNativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"coordinatorLinkPremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Disabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Enabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"}],\"name\":\"FallbackWeiPerUnitLinkUsed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"FulfillmentTxSizeSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeWithdrawn\",\"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\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"WrapperFulfillmentFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUBSCRIPTION_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"isLinkMode\",\"type\":\"bool\"}],\"name\":\"checkPaymentMode\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"coordinatorGasOverheadPerWord\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"wrapperNativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"wrapperLinkPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"link\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNativeFeed\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"requestRandomWordsInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_callbacks\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"requestGasPrice\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_configured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_disabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fulfillmentTxSizeBytes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_coordinatorGasOverheadPerWord\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"_coordinatorNativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"_coordinatorLinkPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"_maxNumWords\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"_stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"_fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"_fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"setFulfillmentTxSize\",\"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\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x60e06040526006805463ffffffff60401b191669024400000000000000001790553480156200002d57600080fd5b5060405162003cc838038062003cc88339810160408190526200005091620002a1565b813380600081620000a85760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000db57620000db81620001d9565b5050506001600160a01b038116620001065760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392831617905584811660a052831660c0526000819003620001505760405163a81c0bef60e01b815260040160405180910390fd5b60025460405163dc311dd360e01b8152600481018390526001600160a01b039091169063dc311dd390602401600060405180830381865afa1580156200019a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001c4919081019062000321565b505050608092909252506200044a9350505050565b336001600160a01b03821603620002335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200029c57600080fd5b919050565b60008060008060808587031215620002b857600080fd5b620002c38562000284565b9350620002d36020860162000284565b9250620002e36040860162000284565b6060959095015193969295505050565b80516001600160601b03811681146200029c57600080fd5b634e487b7160e01b600052604160045260246000fd5b600080600080600060a086880312156200033a57600080fd5b6200034586620002f3565b9450602062000356818801620002f3565b60408801519095506001600160401b0380821682146200037557600080fd5b8195506200038660608a0162000284565b945060808901519150808211156200039d57600080fd5b818901915089601f830112620003b257600080fd5b815181811115620003c757620003c76200030b565b8060051b604051601f19603f83011681018181108582111715620003ef57620003ef6200030b565b60405291825284820192508381018501918c8311156200040e57600080fd5b938501935b828510156200043757620004278562000284565b8452938501939285019262000413565b8096505050505050509295509295909350565b60805160a05160c051613824620004a46000396000818161037e01526122c90152600081816102ca0152818161123b0152818161130a0152611cb401526000818161020b015281816119090152611ea101526138246000f3fe6080604052600436106101c15760003560e01c806357a8070a116100f7578063a4c0ed3611610095578063cdd8d88511610064578063cdd8d88514610747578063e1cab74514610785578063f2fde38b146107a5578063fc2a88c3146107c557600080fd5b8063a4c0ed36146105b9578063a608a1e1146105d9578063bf17e5591461060c578063c3f909d41461062c57600080fd5b80638ea98117116100d15780638ea98117146105445780639cfc058e146105645780639eccacf614610577578063a3907d71146105a457600080fd5b806357a8070a146104c257806379ba5097146105045780638da5cb5b1461051957600080fd5b806321f25aa1116101645780632f2770db1161013e5780632f2770db146103a25780632f622e6b146103b757806348baa1c5146103d757806351cff8d9146104a257600080fd5b806321f25aa11461032f57806327e5c50a1461034f5780632808e6c81461036f57600080fd5b8063181f5a77116101a0578063181f5a771461024d57806318b6f4c8146102995780631c4695f4146102bb5780631fe543e31461030f57600080fd5b806226501b146101c6578063030932bb146101f957806313c34b7f1461022d575b600080fd5b3480156101d257600080fd5b506101e66101e1366004612e4d565b6107db565b6040519081526020015b60405180910390f35b34801561020557600080fd5b506101e67f000000000000000000000000000000000000000000000000000000000000000081565b34801561023957600080fd5b506101e6610248366004612e89565b610915565b34801561025957600080fd5b50604080518082018252601681527f5652465632506c75735772617070657220312e302e3000000000000000000000602082015290516101f09190612f20565b3480156102a557600080fd5b506102b96102b436600461301b565b610a3c565b005b3480156102c757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b34801561031b57600080fd5b506102b961032a36600461306d565b610bbb565b34801561033b57600080fd5b506102b961034a36600461310f565b610c39565b34801561035b57600080fd5b506101e661036a366004612e89565b610f34565b34801561037b57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102ea565b3480156103ae57600080fd5b506102b9611068565b3480156103c357600080fd5b506102b96103d23660046131f1565b6110db565b3480156103e357600080fd5b506104616103f236600461320c565b60076020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000810463ffffffff16907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1683565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff909216602084015267ffffffffffffffff16908201526060016101f0565b3480156104ae57600080fd5b506102b96104bd3660046131f1565b611202565b3480156104ce57600080fd5b506002546104f49074010000000000000000000000000000000000000000900460ff1681565b60405190151581526020016101f0565b34801561051057600080fd5b506102b9611403565b34801561052557600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166102ea565b34801561055057600080fd5b506102b961055f3660046131f1565b611500565b6101e661057236600461326e565b61168b565b34801561058357600080fd5b506002546102ea9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105b057600080fd5b506102b9611b37565b3480156105c557600080fd5b506102b96105d43660046132e4565b611b92565b3480156105e557600080fd5b506002546104f4907501000000000000000000000000000000000000000000900460ff1681565b34801561061857600080fd5b506102b961062736600461333e565b612100565b34801561063857600080fd5b506005546006546003546002546040805194855263ffffffff808516602087015272010000000000000000000000000000000000008504811691860191909152760100000000000000000000000000000000000000000000808504821660608701526401000000008504821660808701526c01000000000000000000000000850490911660a086015261ffff70010000000000000000000000000000000085041660c086015260ff7a0100000000000000000000000000000000000000000000000000008504811660e08701527b0100000000000000000000000000000000000000000000000000000090940484166101008601526101208501929092520416610140820152610160016101f0565b34801561075357600080fd5b506006546107709068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016101f0565b34801561079157600080fd5b506101e66107a0366004612e4d565b612179565b3480156107b157600080fd5b506102b96107c03660046131f1565b612297565b3480156107d157600080fd5b506101e660045481565b60025460009074010000000000000000000000000000000000000000900460ff16610867576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e666967757265640000000000000060448201526064015b60405180910390fd5b6002547501000000000000000000000000000000000000000000900460ff16156108ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161085e565b60006108f76122ab565b50905061090c8563ffffffff16858584612401565b95945050505050565b60025460009074010000000000000000000000000000000000000000900460ff1661099c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161085e565b6002547501000000000000000000000000000000000000000000900460ff1615610a22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161085e565b610a338363ffffffff16833a61255a565b90505b92915050565b8151600003610a805780610a7c576040517f6b81746e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b815160241115610ad15781516040517f51200dce00000000000000000000000000000000000000000000000000000000815261085e9160249160040161ffff92831681529116602082015260400190565b600082602381518110610ae657610ae6613359565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0100000000000000000000000000000000000000000000000000000000000000149050808015610b3c5750815b15610b73576040517f6048aa6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80158015610b7f575081155b15610bb6576040517f6b81746e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610c2e576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161085e565b610bb6838383612668565b610c4161284e565b8163ffffffff168163ffffffff161115610c97576040517f2780dcb200000000000000000000000000000000000000000000000000000000815263ffffffff80831660048301528316602482015260440161085e565b609b60ff89161115610ce1576040517f3acc511a00000000000000000000000000000000000000000000000000000000815260ff89166004820152609b602482015260440161085e565b609b60ff88161115610d2b576040517f3acc511a00000000000000000000000000000000000000000000000000000000815260ff88166004820152609b602482015260440161085e565b8a600660046101000a81548163ffffffff021916908363ffffffff160217905550896006600c6101000a81548163ffffffff021916908363ffffffff16021790555088600660106101000a81548161ffff021916908361ffff160217905550876006601a6101000a81548160ff021916908360ff160217905550866006601b6101000a81548160ff021916908360ff1602179055508560038190555084600260166101000a81548160ff021916908360ff1602179055506001600260146101000a81548160ff02191690831515021790555083600660006101000a81548163ffffffff021916908363ffffffff1602179055508260058190555081600660126101000a81548163ffffffff021916908363ffffffff16021790555080600660166101000a81548163ffffffff021916908363ffffffff1602179055507fc79a05559cababbb44ef05174d6efe2c7107d46ba6691bf92263ee796aaf24568b8b8b8b8b8b8b8b8b8b600660169054906101000a900463ffffffff16604051610f1f9b9a9998979695949392919063ffffffff9b8c168152998b1660208b015261ffff9890981660408a015260ff96871660608a0152948616608089015260a0880193909352931660c086015291851660e085015261010084019190915283166101208301529091166101408201526101600190565b60405180910390a15050505050505050505050565b60025460009074010000000000000000000000000000000000000000900460ff16610fbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161085e565b6002547501000000000000000000000000000000000000000000900460ff1615611041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161085e565b600061104b6122ab565b5090506110608463ffffffff16843a84612401565b949350505050565b61107061284e565b600280547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790556040517f75884cdadc4a89e8b545db800057f06ec7f5338a08183c7ba515f2bfdd9fe1e190600090a1565b6110e361284e565b604051479060009073ffffffffffffffffffffffffffffffffffffffff84169083908381818185875af1925050503d806000811461113d576040519150601f19603f3d011682016040523d82523d6000602084013e611142565b606091505b50509050806111ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6661696c656420746f207769746864726177206e617469766500000000000000604482015260640161085e565b8273ffffffffffffffffffffffffffffffffffffffff167fc303ca808382409472acbbf899c316cf439f409f6584aae22df86dfa3c9ed504836040516111f591815260200190565b60405180910390a2505050565b61120a61284e565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613388565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611355573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137991906133a1565b6113af576040517f7c07fc4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5826040516113f791815260200190565b60405180910390a25050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611484576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161085e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611540575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156115c4573361156560005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161085e565b73ffffffffffffffffffffffffffffffffffffffff8116611611576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fd1a6a14209a385a964d036e404cb5cfb71f4000cdb03c9366292430787261be6906020015b60405180910390a150565b60025460009074010000000000000000000000000000000000000000900460ff16611712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161085e565b6002547501000000000000000000000000000000000000000000900460ff1615611798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161085e565b6117d783838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250610a3c915050565b60006117e2876128d1565b905060006117f78863ffffffff16873a61255a565b905080341015611863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f77000000000000000000000000000000000000000000604482015260640161085e565b600254760100000000000000000000000000000000000000000000900460ff1663ffffffff871611156118f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f2068696768000000000000000000000000000000604482015260640161085e565b60006040518060c0016040528060035481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018961ffff168152602001600660049054906101000a900463ffffffff16858c61195691906133ed565b61196091906133ed565b63ffffffff1681526020018863ffffffff16815260200187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509152506002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90611a06908490600401613411565b6020604051808303816000875af1158015611a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a499190613388565b6040805160608101825233815263ffffffff808d16602080840191825267ffffffffffffffff3a81168587019081526000888152600790935295909120935184549251955190911678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff9590931674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff91909116171792909216919091179055935050505095945050505050565b611b3f61284e565b600280547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690556040517fc0f961051f97b04c496472d11cb6170d844e4b2c9dfd3b602a4fa0139712d48490600090a1565b60025474010000000000000000000000000000000000000000900460ff16611c16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161085e565b6002547501000000000000000000000000000000000000000000900460ff1615611c9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161085e565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611d3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b000000000000000000604482015260640161085e565b6000808080611d4c8587018761346e565b9350935093509350611d5f816001610a3c565b6000611d6a856128d1565b9050600080611d776122ab565b915091506000611d8f8863ffffffff16873a86612401565b9050808b1015611dfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f77000000000000000000000000000000000000000000604482015260640161085e565b600254760100000000000000000000000000000000000000000000900460ff1663ffffffff87161115611e8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f2068696768000000000000000000000000000000604482015260640161085e565b60006040518060c0016040528060035481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018961ffff168152602001600660049054906101000a900463ffffffff16878c611eee91906133ed565b611ef891906133ed565b63ffffffff908116825289166020820152604090810188905260025490517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90611f6c908590600401613411565b6020604051808303816000875af1158015611f8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611faf9190613388565b905060405180606001604052808f73ffffffffffffffffffffffffffffffffffffffff1681526020018b63ffffffff1681526020013a67ffffffffffffffff168152506007600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050508060048190555083156120f0576005546040805183815260208101929092527f6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a910160405180910390a15b5050505050505050505050505050565b61210861284e565b600680547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff8416908102919091179091556040519081527f697b48b8b76cebb09a54ec4ff810e8a181c96f65395d51c744db09c115d1d5d090602001611680565b60025460009074010000000000000000000000000000000000000000900460ff16612200576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e6669677572656400000000000000604482015260640161085e565b6002547501000000000000000000000000000000000000000000900460ff1615612286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c656400000000000000000000000000604482015260640161085e565b6110608463ffffffff16848461255a565b61229f61284e565b6122a8816128e9565b50565b6000806000600660009054906101000a900463ffffffff16905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015612332573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235691906134f7565b50919650909250505063ffffffff82161580159061238257506123798142613547565b8263ffffffff16105b925082156123905760055493505b60008412156123fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b2077656920707269636500000000000000000000604482015260640161085e565b50509091565b600654600090819061242190640100000000900463ffffffff168561355a565b6006549091506000906124459068010000000000000000900463ffffffff166129de565b61244e87612aa6565b61245e9063ffffffff1689613571565b612468908761355a565b6124729190613571565b6006549091506000906124bd9063ffffffff76010000000000000000000000000000000000000000000082048116917201000000000000000000000000000000000000900416613584565b6124d29063ffffffff1664e8d4a5100061355a565b600654606490612504907b01000000000000000000000000000000000000000000000000000000900460ff16826135a1565b6125119060ff168561355a565b61251b91906135e9565b6125259190613571565b9050846125328285613571565b61254490670de0b6b3a764000061355a565b61254e91906135e9565b98975050505050505050565b600654600090819061257a90640100000000900463ffffffff168461355a565b60065490915060009061259e9068010000000000000000900463ffffffff166129de565b6125a786612aa6565b6125b79063ffffffff1688613571565b6125c1908661355a565b6125cb9190613571565b6006549091506000906125ff907201000000000000000000000000000000000000900463ffffffff1664e8d4a5100061355a565b600654606490612630907a010000000000000000000000000000000000000000000000000000900460ff16826135a1565b61263d9060ff168561355a565b61264791906135e9565b6126519190613571565b905061265d8184613571565b979650505050505050565b60008381526007602081815260408084208151606081018352815473ffffffffffffffffffffffffffffffffffffffff808216835274010000000000000000000000000000000000000000820463ffffffff1683870152780100000000000000000000000000000000000000000000000090910467ffffffffffffffff169382019390935288865293909252929055805190918116612763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e64000000000000000000000000000000604482015260640161085e565b600080631fe543e360e01b878787604051602401612783939291906135fd565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060006127f9856020015163ffffffff168584612af1565b9050806128445760405173ffffffffffffffffffffffffffffffffffffffff85169089907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146128cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161085e565b565b60006128de603f83613656565b610a369060016133ed565b3373ffffffffffffffffffffffffffffffffffffffff821603612968576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161085e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000466129ea81612b3d565b15612a7f576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa158015612a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a619190613679565b5050505091505083608c612a759190613571565b611060908261355a565b612a8881612b60565b15612a9d57612a9683612b9a565b9392505050565b50600092915050565b600654600090612ace90700100000000000000000000000000000000900461ffff16836136c3565b600654610a3691906c01000000000000000000000000900463ffffffff166133ed565b60005a611388811015612b0357600080fd5b611388810390508460408204820311612b1b57600080fd5b50823b612b2757600080fd5b60008083516020850160008789f1949350505050565b600061a4b1821480612b51575062066eed82145b80610a3657505062066eee1490565b6000600a821480612b7257506101a482145b80612b7f575062aa37dc82145b80612b8b575061210582145b80610a3657505062014a331490565b60008073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663519b4bd36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c209190613388565b9050600080612c2f8186613547565b90506000612c3e82601061355a565b612c4984600461355a565b612c539190613571565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff16630c18c1626040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cda9190613388565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663f45e65d86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d619190613388565b9050600073420000000000000000000000000000000000000f73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612de89190613388565b90506000612df782600a61380b565b905060008184612e078789613571565b612e11908c61355a565b612e1b919061355a565b612e2591906135e9565b9b9a5050505050505050505050565b803563ffffffff81168114612e4857600080fd5b919050565b600080600060608486031215612e6257600080fd5b612e6b84612e34565b9250612e7960208501612e34565b9150604084013590509250925092565b60008060408385031215612e9c57600080fd5b612ea583612e34565b9150612eb360208401612e34565b90509250929050565b6000815180845260005b81811015612ee257602081850181015186830182015201612ec6565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610a336020830184612ebc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612f7357600080fd5b813567ffffffffffffffff80821115612f8e57612f8e612f33565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612fd457612fd4612f33565b81604052838152866020858801011115612fed57600080fd5b836020870160208301376000602085830101528094505050505092915050565b80151581146122a857600080fd5b6000806040838503121561302e57600080fd5b823567ffffffffffffffff81111561304557600080fd5b61305185828601612f62565b92505060208301356130628161300d565b809150509250929050565b60008060006040848603121561308257600080fd5b83359250602084013567ffffffffffffffff808211156130a157600080fd5b818601915086601f8301126130b557600080fd5b8135818111156130c457600080fd5b8760208260051b85010111156130d957600080fd5b6020830194508093505050509250925092565b803561ffff81168114612e4857600080fd5b803560ff81168114612e4857600080fd5b60008060008060008060008060008060006101608c8e03121561313157600080fd5b61313a8c612e34565b9a5061314860208d01612e34565b995061315660408d016130ec565b985061316460608d016130fe565b975061317260808d016130fe565b965060a08c0135955061318760c08d016130fe565b945061319560e08d01612e34565b93506101008c013592506131ac6101208d01612e34565b91506131bb6101408d01612e34565b90509295989b509295989b9093969950565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e4857600080fd5b60006020828403121561320357600080fd5b610a33826131cd565b60006020828403121561321e57600080fd5b5035919050565b60008083601f84011261323757600080fd5b50813567ffffffffffffffff81111561324f57600080fd5b60208301915083602082850101111561326757600080fd5b9250929050565b60008060008060006080868803121561328657600080fd5b61328f86612e34565b945061329d602087016130ec565b93506132ab60408701612e34565b9250606086013567ffffffffffffffff8111156132c757600080fd5b6132d388828901613225565b969995985093965092949392505050565b600080600080606085870312156132fa57600080fd5b613303856131cd565b935060208501359250604085013567ffffffffffffffff81111561332657600080fd5b61333287828801613225565b95989497509550505050565b60006020828403121561335057600080fd5b610a3382612e34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561339a57600080fd5b5051919050565b6000602082840312156133b357600080fd5b8151612a968161300d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff81811683821601908082111561340a5761340a6133be565b5092915050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261106060e0840182612ebc565b6000806000806080858703121561348457600080fd5b61348d85612e34565b935061349b602086016130ec565b92506134a960408601612e34565b9150606085013567ffffffffffffffff8111156134c557600080fd5b6134d187828801612f62565b91505092959194509250565b805169ffffffffffffffffffff81168114612e4857600080fd5b600080600080600060a0868803121561350f57600080fd5b613518866134dd565b945060208601519350604086015192506060860151915061353b608087016134dd565b90509295509295909350565b81810381811115610a3657610a366133be565b8082028115828204841417610a3657610a366133be565b80820180821115610a3657610a366133be565b63ffffffff82811682821603908082111561340a5761340a6133be565b60ff8181168382160190811115610a3657610a366133be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826135f8576135f86135ba565b500490565b8381526040602082015281604082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561363c57600080fd5b8260051b8085606085013791909101606001949350505050565b600063ffffffff8084168061366d5761366d6135ba565b92169190910492915050565b60008060008060008060c0878903121561369257600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b63ffffffff8181168382160280821691908281146136e3576136e36133be565b505092915050565b600181815b8085111561374457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561372a5761372a6133be565b8085161561373757918102915b93841c93908002906136f0565b509250929050565b60008261375b57506001610a36565b8161376857506000610a36565b816001811461377e5760028114613788576137a4565b6001915050610a36565b60ff841115613799576137996133be565b50506001821b610a36565b5060208310610133831016604e8410600b84101617156137c7575081810a610a36565b6137d183836136eb565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613803576138036133be565b029392505050565b6000610a33838361374c56fea164736f6c6343000813000a",
}
var VRFV2PlusWrapperABI = VRFV2PlusWrapperMetaData.ABI
@@ -193,9 +193,9 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) SUBSCRIPTIONID() (*big.I
return _VRFV2PlusWrapper.Contract.SUBSCRIPTIONID(&_VRFV2PlusWrapper.CallOpts)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) CalculateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32) (*big.Int, error) {
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) CalculateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32, _numWords uint32) (*big.Int, error) {
var out []interface{}
- err := _VRFV2PlusWrapper.contract.Call(opts, &out, "calculateRequestPrice", _callbackGasLimit)
+ err := _VRFV2PlusWrapper.contract.Call(opts, &out, "calculateRequestPrice", _callbackGasLimit, _numWords)
if err != nil {
return *new(*big.Int), err
@@ -207,17 +207,17 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) CalculateRequestPrice(opts *bin
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) CalculateRequestPrice(_callbackGasLimit uint32) (*big.Int, error) {
- return _VRFV2PlusWrapper.Contract.CalculateRequestPrice(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) CalculateRequestPrice(_callbackGasLimit uint32, _numWords uint32) (*big.Int, error) {
+ return _VRFV2PlusWrapper.Contract.CalculateRequestPrice(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _numWords)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) CalculateRequestPrice(_callbackGasLimit uint32) (*big.Int, error) {
- return _VRFV2PlusWrapper.Contract.CalculateRequestPrice(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) CalculateRequestPrice(_callbackGasLimit uint32, _numWords uint32) (*big.Int, error) {
+ return _VRFV2PlusWrapper.Contract.CalculateRequestPrice(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _numWords)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) CalculateRequestPriceNative(opts *bind.CallOpts, _callbackGasLimit uint32) (*big.Int, error) {
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) CalculateRequestPriceNative(opts *bind.CallOpts, _callbackGasLimit uint32, _numWords uint32) (*big.Int, error) {
var out []interface{}
- err := _VRFV2PlusWrapper.contract.Call(opts, &out, "calculateRequestPriceNative", _callbackGasLimit)
+ err := _VRFV2PlusWrapper.contract.Call(opts, &out, "calculateRequestPriceNative", _callbackGasLimit, _numWords)
if err != nil {
return *new(*big.Int), err
@@ -229,12 +229,12 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) CalculateRequestPriceNative(opt
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) CalculateRequestPriceNative(_callbackGasLimit uint32) (*big.Int, error) {
- return _VRFV2PlusWrapper.Contract.CalculateRequestPriceNative(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) CalculateRequestPriceNative(_callbackGasLimit uint32, _numWords uint32) (*big.Int, error) {
+ return _VRFV2PlusWrapper.Contract.CalculateRequestPriceNative(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _numWords)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) CalculateRequestPriceNative(_callbackGasLimit uint32) (*big.Int, error) {
- return _VRFV2PlusWrapper.Contract.CalculateRequestPriceNative(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) CalculateRequestPriceNative(_callbackGasLimit uint32, _numWords uint32) (*big.Int, error) {
+ return _VRFV2PlusWrapper.Contract.CalculateRequestPriceNative(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _numWords)
}
func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) CheckPaymentMode(opts *bind.CallOpts, extraArgs []byte, isLinkMode bool) error {
@@ -257,9 +257,9 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) CheckPaymentMode(extraAr
return _VRFV2PlusWrapper.Contract.CheckPaymentMode(&_VRFV2PlusWrapper.CallOpts, extraArgs, isLinkMode)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) EstimateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) EstimateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32, _numWords uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
var out []interface{}
- err := _VRFV2PlusWrapper.contract.Call(opts, &out, "estimateRequestPrice", _callbackGasLimit, _requestGasPriceWei)
+ err := _VRFV2PlusWrapper.contract.Call(opts, &out, "estimateRequestPrice", _callbackGasLimit, _numWords, _requestGasPriceWei)
if err != nil {
return *new(*big.Int), err
@@ -271,17 +271,17 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) EstimateRequestPrice(opts *bind
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) EstimateRequestPrice(_callbackGasLimit uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
- return _VRFV2PlusWrapper.Contract.EstimateRequestPrice(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _requestGasPriceWei)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) EstimateRequestPrice(_callbackGasLimit uint32, _numWords uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
+ return _VRFV2PlusWrapper.Contract.EstimateRequestPrice(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _numWords, _requestGasPriceWei)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) EstimateRequestPrice(_callbackGasLimit uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
- return _VRFV2PlusWrapper.Contract.EstimateRequestPrice(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _requestGasPriceWei)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) EstimateRequestPrice(_callbackGasLimit uint32, _numWords uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
+ return _VRFV2PlusWrapper.Contract.EstimateRequestPrice(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _numWords, _requestGasPriceWei)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) EstimateRequestPriceNative(opts *bind.CallOpts, _callbackGasLimit uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) EstimateRequestPriceNative(opts *bind.CallOpts, _callbackGasLimit uint32, _numWords uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
var out []interface{}
- err := _VRFV2PlusWrapper.contract.Call(opts, &out, "estimateRequestPriceNative", _callbackGasLimit, _requestGasPriceWei)
+ err := _VRFV2PlusWrapper.contract.Call(opts, &out, "estimateRequestPriceNative", _callbackGasLimit, _numWords, _requestGasPriceWei)
if err != nil {
return *new(*big.Int), err
@@ -293,12 +293,12 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) EstimateRequestPriceNative(opts
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) EstimateRequestPriceNative(_callbackGasLimit uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
- return _VRFV2PlusWrapper.Contract.EstimateRequestPriceNative(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _requestGasPriceWei)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) EstimateRequestPriceNative(_callbackGasLimit uint32, _numWords uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
+ return _VRFV2PlusWrapper.Contract.EstimateRequestPriceNative(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _numWords, _requestGasPriceWei)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) EstimateRequestPriceNative(_callbackGasLimit uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
- return _VRFV2PlusWrapper.Contract.EstimateRequestPriceNative(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _requestGasPriceWei)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) EstimateRequestPriceNative(_callbackGasLimit uint32, _numWords uint32, _requestGasPriceWei *big.Int) (*big.Int, error) {
+ return _VRFV2PlusWrapper.Contract.EstimateRequestPriceNative(&_VRFV2PlusWrapper.CallOpts, _callbackGasLimit, _numWords, _requestGasPriceWei)
}
func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) GetConfig(opts *bind.CallOpts) (GetConfig,
@@ -318,10 +318,11 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) GetConfig(opts *bind.CallOpts)
outstruct.FulfillmentFlatFeeLinkDiscountPPM = *abi.ConvertType(out[3], new(uint32)).(*uint32)
outstruct.WrapperGasOverhead = *abi.ConvertType(out[4], new(uint32)).(*uint32)
outstruct.CoordinatorGasOverhead = *abi.ConvertType(out[5], new(uint32)).(*uint32)
- outstruct.WrapperNativePremiumPercentage = *abi.ConvertType(out[6], new(uint8)).(*uint8)
- outstruct.WrapperLinkPremiumPercentage = *abi.ConvertType(out[7], new(uint8)).(*uint8)
- outstruct.KeyHash = *abi.ConvertType(out[8], new([32]byte)).(*[32]byte)
- outstruct.MaxNumWords = *abi.ConvertType(out[9], new(uint8)).(*uint8)
+ outstruct.CoordinatorGasOverheadPerWord = *abi.ConvertType(out[6], new(uint16)).(*uint16)
+ outstruct.WrapperNativePremiumPercentage = *abi.ConvertType(out[7], new(uint8)).(*uint8)
+ outstruct.WrapperLinkPremiumPercentage = *abi.ConvertType(out[8], new(uint8)).(*uint8)
+ outstruct.KeyHash = *abi.ConvertType(out[9], new([32]byte)).(*[32]byte)
+ outstruct.MaxNumWords = *abi.ConvertType(out[10], new(uint8)).(*uint8)
return *outstruct, err
@@ -640,16 +641,16 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) RequestRandomWordsIn
return _VRFV2PlusWrapper.Contract.RequestRandomWordsInNative(&_VRFV2PlusWrapper.TransactOpts, _callbackGasLimit, _requestConfirmations, _numWords, extraArgs)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) SetConfig(opts *bind.TransactOpts, _wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _coordinatorNativePremiumPercentage uint8, _coordinatorLinkPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, _stalenessSeconds uint32, _fallbackWeiPerUnitLink *big.Int, _fulfillmentFlatFeeNativePPM uint32, _fulfillmentFlatFeeLinkDiscountPPM uint32) (*types.Transaction, error) {
- return _VRFV2PlusWrapper.contract.Transact(opts, "setConfig", _wrapperGasOverhead, _coordinatorGasOverhead, _coordinatorNativePremiumPercentage, _coordinatorLinkPremiumPercentage, _keyHash, _maxNumWords, _stalenessSeconds, _fallbackWeiPerUnitLink, _fulfillmentFlatFeeNativePPM, _fulfillmentFlatFeeLinkDiscountPPM)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) SetConfig(opts *bind.TransactOpts, _wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _coordinatorGasOverheadPerWord uint16, _coordinatorNativePremiumPercentage uint8, _coordinatorLinkPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, _stalenessSeconds uint32, _fallbackWeiPerUnitLink *big.Int, _fulfillmentFlatFeeNativePPM uint32, _fulfillmentFlatFeeLinkDiscountPPM uint32) (*types.Transaction, error) {
+ return _VRFV2PlusWrapper.contract.Transact(opts, "setConfig", _wrapperGasOverhead, _coordinatorGasOverhead, _coordinatorGasOverheadPerWord, _coordinatorNativePremiumPercentage, _coordinatorLinkPremiumPercentage, _keyHash, _maxNumWords, _stalenessSeconds, _fallbackWeiPerUnitLink, _fulfillmentFlatFeeNativePPM, _fulfillmentFlatFeeLinkDiscountPPM)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SetConfig(_wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _coordinatorNativePremiumPercentage uint8, _coordinatorLinkPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, _stalenessSeconds uint32, _fallbackWeiPerUnitLink *big.Int, _fulfillmentFlatFeeNativePPM uint32, _fulfillmentFlatFeeLinkDiscountPPM uint32) (*types.Transaction, error) {
- return _VRFV2PlusWrapper.Contract.SetConfig(&_VRFV2PlusWrapper.TransactOpts, _wrapperGasOverhead, _coordinatorGasOverhead, _coordinatorNativePremiumPercentage, _coordinatorLinkPremiumPercentage, _keyHash, _maxNumWords, _stalenessSeconds, _fallbackWeiPerUnitLink, _fulfillmentFlatFeeNativePPM, _fulfillmentFlatFeeLinkDiscountPPM)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SetConfig(_wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _coordinatorGasOverheadPerWord uint16, _coordinatorNativePremiumPercentage uint8, _coordinatorLinkPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, _stalenessSeconds uint32, _fallbackWeiPerUnitLink *big.Int, _fulfillmentFlatFeeNativePPM uint32, _fulfillmentFlatFeeLinkDiscountPPM uint32) (*types.Transaction, error) {
+ return _VRFV2PlusWrapper.Contract.SetConfig(&_VRFV2PlusWrapper.TransactOpts, _wrapperGasOverhead, _coordinatorGasOverhead, _coordinatorGasOverheadPerWord, _coordinatorNativePremiumPercentage, _coordinatorLinkPremiumPercentage, _keyHash, _maxNumWords, _stalenessSeconds, _fallbackWeiPerUnitLink, _fulfillmentFlatFeeNativePPM, _fulfillmentFlatFeeLinkDiscountPPM)
}
-func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) SetConfig(_wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _coordinatorNativePremiumPercentage uint8, _coordinatorLinkPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, _stalenessSeconds uint32, _fallbackWeiPerUnitLink *big.Int, _fulfillmentFlatFeeNativePPM uint32, _fulfillmentFlatFeeLinkDiscountPPM uint32) (*types.Transaction, error) {
- return _VRFV2PlusWrapper.Contract.SetConfig(&_VRFV2PlusWrapper.TransactOpts, _wrapperGasOverhead, _coordinatorGasOverhead, _coordinatorNativePremiumPercentage, _coordinatorLinkPremiumPercentage, _keyHash, _maxNumWords, _stalenessSeconds, _fallbackWeiPerUnitLink, _fulfillmentFlatFeeNativePPM, _fulfillmentFlatFeeLinkDiscountPPM)
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) SetConfig(_wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _coordinatorGasOverheadPerWord uint16, _coordinatorNativePremiumPercentage uint8, _coordinatorLinkPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, _stalenessSeconds uint32, _fallbackWeiPerUnitLink *big.Int, _fulfillmentFlatFeeNativePPM uint32, _fulfillmentFlatFeeLinkDiscountPPM uint32) (*types.Transaction, error) {
+ return _VRFV2PlusWrapper.Contract.SetConfig(&_VRFV2PlusWrapper.TransactOpts, _wrapperGasOverhead, _coordinatorGasOverhead, _coordinatorGasOverheadPerWord, _coordinatorNativePremiumPercentage, _coordinatorLinkPremiumPercentage, _keyHash, _maxNumWords, _stalenessSeconds, _fallbackWeiPerUnitLink, _fulfillmentFlatFeeNativePPM, _fulfillmentFlatFeeLinkDiscountPPM)
}
func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error) {
@@ -775,6 +776,7 @@ func (it *VRFV2PlusWrapperConfigSetIterator) Close() error {
type VRFV2PlusWrapperConfigSet struct {
WrapperGasOverhead uint32
CoordinatorGasOverhead uint32
+ CoordinatorGasOverheadPerWord uint16
CoordinatorNativePremiumPercentage uint8
CoordinatorLinkPremiumPercentage uint8
KeyHash [32]byte
@@ -2093,6 +2095,7 @@ type GetConfig struct {
FulfillmentFlatFeeLinkDiscountPPM uint32
WrapperGasOverhead uint32
CoordinatorGasOverhead uint32
+ CoordinatorGasOverheadPerWord uint16
WrapperNativePremiumPercentage uint8
WrapperLinkPremiumPercentage uint8
KeyHash [32]byte
@@ -2135,7 +2138,7 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapper) ParseLog(log types.Log) (generated.Ab
}
func (VRFV2PlusWrapperConfigSet) Topic() common.Hash {
- return common.HexToHash("0xb18fd84519589131d50ae195b0aea1b042c3c0b25a53bb894d9d81c78980c20f")
+ return common.HexToHash("0xc79a05559cababbb44ef05174d6efe2c7107d46ba6691bf92263ee796aaf2456")
}
func (VRFV2PlusWrapperCoordinatorSet) Topic() common.Hash {
@@ -2185,15 +2188,15 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapper) Address() common.Address {
type VRFV2PlusWrapperInterface interface {
SUBSCRIPTIONID(opts *bind.CallOpts) (*big.Int, error)
- CalculateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32) (*big.Int, error)
+ CalculateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32, _numWords uint32) (*big.Int, error)
- CalculateRequestPriceNative(opts *bind.CallOpts, _callbackGasLimit uint32) (*big.Int, error)
+ CalculateRequestPriceNative(opts *bind.CallOpts, _callbackGasLimit uint32, _numWords uint32) (*big.Int, error)
CheckPaymentMode(opts *bind.CallOpts, extraArgs []byte, isLinkMode bool) error
- EstimateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32, _requestGasPriceWei *big.Int) (*big.Int, error)
+ EstimateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32, _numWords uint32, _requestGasPriceWei *big.Int) (*big.Int, error)
- EstimateRequestPriceNative(opts *bind.CallOpts, _callbackGasLimit uint32, _requestGasPriceWei *big.Int) (*big.Int, error)
+ EstimateRequestPriceNative(opts *bind.CallOpts, _callbackGasLimit uint32, _numWords uint32, _requestGasPriceWei *big.Int) (*big.Int, error)
GetConfig(opts *bind.CallOpts) (GetConfig,
@@ -2233,7 +2236,7 @@ type VRFV2PlusWrapperInterface interface {
RequestRandomWordsInNative(opts *bind.TransactOpts, _callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, extraArgs []byte) (*types.Transaction, error)
- SetConfig(opts *bind.TransactOpts, _wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _coordinatorNativePremiumPercentage uint8, _coordinatorLinkPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, _stalenessSeconds uint32, _fallbackWeiPerUnitLink *big.Int, _fulfillmentFlatFeeNativePPM uint32, _fulfillmentFlatFeeLinkDiscountPPM uint32) (*types.Transaction, error)
+ SetConfig(opts *bind.TransactOpts, _wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _coordinatorGasOverheadPerWord uint16, _coordinatorNativePremiumPercentage uint8, _coordinatorLinkPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, _stalenessSeconds uint32, _fallbackWeiPerUnitLink *big.Int, _fulfillmentFlatFeeNativePPM uint32, _fulfillmentFlatFeeLinkDiscountPPM uint32) (*types.Transaction, error)
SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error)
diff --git a/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example/vrfv2plus_wrapper_consumer_example.go b/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example/vrfv2plus_wrapper_consumer_example.go
index 094d57a9adc..4a4370bdf5e 100644
--- a/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example/vrfv2plus_wrapper_consumer_example.go
+++ b/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example/vrfv2plus_wrapper_consumer_example.go
@@ -32,7 +32,7 @@ var (
var VRFV2PlusWrapperConsumerExampleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfV2Wrapper\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyVRFWrapperCanFulfill\",\"type\":\"error\"},{\"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\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"WrappedRequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"}],\"name\":\"WrapperRequestMade\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_vrfV2PlusWrapper\",\"outputs\":[{\"internalType\":\"contractIVRFV2PlusWrapper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"makeRequest\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"makeRequestNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"native\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60c06040523480156200001157600080fd5b5060405162001662380380620016628339810160408190526200003491620001f5565b33806000836000819050806001600160a01b0316631c4695f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200007d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a39190620001f5565b6001600160a01b0390811660805290811660a052831690506200010d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001405762000140816200014a565b5050505062000227565b336001600160a01b03821603620001a45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000104565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200020857600080fd5b81516001600160a01b03811681146200022057600080fd5b9392505050565b60805160a0516113dd62000285600039600081816101aa0152818161047b01528181610aa801528181610b5301528181610bfd01528181610ce30152610d52015260008181610242015281816106220152610b1701526113dd6000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806384276d811161008c578063a168fa8911610066578063a168fa89146101cc578063d8a4676f1461021e578063e76d516814610240578063f2fde38b1461026657600080fd5b806384276d81146101535780638da5cb5b146101665780639ed0868d146101a557600080fd5b80631fe543e3116100bd5780631fe543e31461012357806379ba5097146101385780637a8042bd1461014057600080fd5b80630c09b832146100e457806312065fe01461010a5780631e1a349914610110575b600080fd5b6100f76100f2366004611078565b610279565b6040519081526020015b60405180910390f35b476100f7565b6100f761011e366004611078565b6103b4565b6101366101313660046110f3565b610479565b005b61013661051b565b61013661014e3660046111db565b610618565b6101366101613660046111db565b610715565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610101565b6101807f000000000000000000000000000000000000000000000000000000000000000081565b6102016101da3660046111db565b600260205260009081526040902080546001820154600390920154909160ff908116911683565b604080519384529115156020840152151590820152606001610101565b61023161022c3660046111db565b6107e7565b6040516101019392919061122f565b7f0000000000000000000000000000000000000000000000000000000000000000610180565b610136610274366004611259565b610907565b600061028361091b565b600061029f60405180602001604052806000151581525061099e565b905060006102af86868685610a5a565b604080516080810182528281526000602080830182815284518381528083018652848601908152606085018490528784526002808452959093208451815590516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055915180519699509496509194909361033c938501920190610fff565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560405181815283907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec49060200160405180910390a250509392505050565b60006103be61091b565b60006103da60405180602001604052806001151581525061099e565b905060006103ea86868685610c95565b60408051608081018252828152600060208083018281528451838152808301865284860190815260016060860181905288855260028085529690942085518155915193820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001694151594909417909355915180519699509496509194909361033c938501920190610fff565b7f00000000000000000000000000000000000000000000000000000000000000003373ffffffffffffffffffffffffffffffffffffffff82161461050c576040517f8ba9316e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b6105168383610df3565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461059c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610503565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61062061091b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61067b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af11580156106ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107119190611296565b5050565b61071d61091b565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169083908381818185875af1925050503d8060008114610777576040519150601f19603f3d011682016040523d82523d6000602084013e61077c565b606091505b5050905080610711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f77697468647261774e6174697665206661696c656400000000000000000000006044820152606401610503565b6000818152600260205260408120548190606090610861576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610503565b6000848152600260208181526040808420815160808101835281548152600182015460ff16151581850152938101805483518186028101860185528181529294938601938301828280156108d457602002820191906000526020600020905b8154815260200190600101908083116108c0575b50505091835250506003919091015460ff1615156020918201528151908201516040909201519097919650945092505050565b61090f61091b565b61091881610f0a565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461099c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610503565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016109d791511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b6040517f4306d35400000000000000000000000000000000000000000000000000000000815263ffffffff85166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634306d35490602401602060405180830381865afa158015610aef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1391906112b8565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea07f00000000000000000000000000000000000000000000000000000000000000008389898989604051602001610b8a9493929190611335565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401610bb793929190611372565b6020604051808303816000875af1158015610bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfa9190611296565b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fc2a88c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8a91906112b8565b915094509492505050565b6040517f4b16093500000000000000000000000000000000000000000000000000000000815263ffffffff85166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634b16093590602401602060405180830381865afa158015610d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4e91906112b8565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639cfc058e82888888886040518663ffffffff1660e01b8152600401610db09493929190611335565b60206040518083038185885af1158015610dce573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610c8a91906112b8565b600082815260026020526040902054610e68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610503565b6000828152600260208181526040909220600181810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790558351610ebb93919092019190840190610fff565b50600082815260026020526040908190205490517f6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b91610efe91859185916113a7565b60405180910390a15050565b3373ffffffffffffffffffffffffffffffffffffffff821603610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610503565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821561103a579160200282015b8281111561103a57825182559160200191906001019061101f565b5061104692915061104a565b5090565b5b80821115611046576000815560010161104b565b803563ffffffff8116811461107357600080fd5b919050565b60008060006060848603121561108d57600080fd5b6110968461105f565b9250602084013561ffff811681146110ad57600080fd5b91506110bb6040850161105f565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561110657600080fd5b8235915060208084013567ffffffffffffffff8082111561112657600080fd5b818601915086601f83011261113a57600080fd5b81358181111561114c5761114c6110c4565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561118f5761118f6110c4565b6040529182528482019250838101850191898311156111ad57600080fd5b938501935b828510156111cb578435845293850193928501926111b2565b8096505050505050509250929050565b6000602082840312156111ed57600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561122457815187529582019590820190600101611208565b509495945050505050565b838152821515602082015260606040820152600061125060608301846111f4565b95945050505050565b60006020828403121561126b57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461128f57600080fd5b9392505050565b6000602082840312156112a857600080fd5b8151801515811461128f57600080fd5b6000602082840312156112ca57600080fd5b5051919050565b6000815180845260005b818110156112f7576020818501810151868301820152016112db565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600063ffffffff808716835261ffff861660208401528085166040840152506080606083015261136860808301846112d1565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061125060608301846112d1565b8381526060602082015260006113c060608301856111f4565b905082604083015294935050505056fea164736f6c6343000813000a",
+ Bin: "0x60c06040523480156200001157600080fd5b5060405162001672380380620016728339810160408190526200003491620001f5565b33806000836000819050806001600160a01b0316631c4695f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200007d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a39190620001f5565b6001600160a01b0390811660805290811660a052831690506200010d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001405762000140816200014a565b5050505062000227565b336001600160a01b03821603620001a45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000104565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200020857600080fd5b81516001600160a01b03811681146200022057600080fd5b9392505050565b60805160a0516113ed62000285600039600081816101aa0152818161047b01528181610ab001528181610b5b01528181610c0501528181610cf30152610d62015260008181610242015281816106220152610b1f01526113ed6000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806384276d811161008c578063a168fa8911610066578063a168fa89146101cc578063d8a4676f1461021e578063e76d516814610240578063f2fde38b1461026657600080fd5b806384276d81146101535780638da5cb5b146101665780639ed0868d146101a557600080fd5b80631fe543e3116100bd5780631fe543e31461012357806379ba5097146101385780637a8042bd1461014057600080fd5b80630c09b832146100e457806312065fe01461010a5780631e1a349914610110575b600080fd5b6100f76100f2366004611088565b610279565b6040519081526020015b60405180910390f35b476100f7565b6100f761011e366004611088565b6103b4565b610136610131366004611103565b610479565b005b61013661051b565b61013661014e3660046111eb565b610618565b6101366101613660046111eb565b610715565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610101565b6101807f000000000000000000000000000000000000000000000000000000000000000081565b6102016101da3660046111eb565b600260205260009081526040902080546001820154600390920154909160ff908116911683565b604080519384529115156020840152151590820152606001610101565b61023161022c3660046111eb565b6107e7565b6040516101019392919061123f565b7f0000000000000000000000000000000000000000000000000000000000000000610180565b610136610274366004611269565b610907565b600061028361091b565b600061029f60405180602001604052806000151581525061099e565b905060006102af86868685610a5a565b604080516080810182528281526000602080830182815284518381528083018652848601908152606085018490528784526002808452959093208451815590516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055915180519699509496509194909361033c93850192019061100f565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560405181815283907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec49060200160405180910390a250509392505050565b60006103be61091b565b60006103da60405180602001604052806001151581525061099e565b905060006103ea86868685610c9d565b60408051608081018252828152600060208083018281528451838152808301865284860190815260016060860181905288855260028085529690942085518155915193820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001694151594909417909355915180519699509496509194909361033c93850192019061100f565b7f00000000000000000000000000000000000000000000000000000000000000003373ffffffffffffffffffffffffffffffffffffffff82161461050c576040517f8ba9316e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b6105168383610e03565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461059c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610503565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61062061091b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61067b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af11580156106ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071191906112a6565b5050565b61071d61091b565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169083908381818185875af1925050503d8060008114610777576040519150601f19603f3d011682016040523d82523d6000602084013e61077c565b606091505b5050905080610711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f77697468647261774e6174697665206661696c656400000000000000000000006044820152606401610503565b6000818152600260205260408120548190606090610861576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610503565b6000848152600260208181526040808420815160808101835281548152600182015460ff16151581850152938101805483518186028101860185528181529294938601938301828280156108d457602002820191906000526020600020905b8154815260200190600101908083116108c0575b50505091835250506003919091015460ff1615156020918201528151908201516040909201519097919650945092505050565b61090f61091b565b61091881610f1a565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461099c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610503565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016109d791511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b6040517f27e5c50a00000000000000000000000000000000000000000000000000000000815263ffffffff808616600483015283166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906327e5c50a90604401602060405180830381865afa158015610af7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1b91906112c8565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea07f00000000000000000000000000000000000000000000000000000000000000008389898989604051602001610b929493929190611345565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401610bbf93929190611382565b6020604051808303816000875af1158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0291906112a6565b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fc2a88c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9291906112c8565b915094509492505050565b6040517f13c34b7f00000000000000000000000000000000000000000000000000000000815263ffffffff808616600483015283166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906313c34b7f90604401602060405180830381865afa158015610d3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5e91906112c8565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639cfc058e82888888886040518663ffffffff1660e01b8152600401610dc09493929190611345565b60206040518083038185885af1158015610dde573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610c9291906112c8565b600082815260026020526040902054610e78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610503565b6000828152600260208181526040909220600181810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790558351610ecb9391909201919084019061100f565b50600082815260026020526040908190205490517f6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b91610f0e91859185916113b7565b60405180910390a15050565b3373ffffffffffffffffffffffffffffffffffffffff821603610f99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610503565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821561104a579160200282015b8281111561104a57825182559160200191906001019061102f565b5061105692915061105a565b5090565b5b80821115611056576000815560010161105b565b803563ffffffff8116811461108357600080fd5b919050565b60008060006060848603121561109d57600080fd5b6110a68461106f565b9250602084013561ffff811681146110bd57600080fd5b91506110cb6040850161106f565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561111657600080fd5b8235915060208084013567ffffffffffffffff8082111561113657600080fd5b818601915086601f83011261114a57600080fd5b81358181111561115c5761115c6110d4565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561119f5761119f6110d4565b6040529182528482019250838101850191898311156111bd57600080fd5b938501935b828510156111db578435845293850193928501926111c2565b8096505050505050509250929050565b6000602082840312156111fd57600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561123457815187529582019590820190600101611218565b509495945050505050565b83815282151560208201526060604082015260006112606060830184611204565b95945050505050565b60006020828403121561127b57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461129f57600080fd5b9392505050565b6000602082840312156112b857600080fd5b8151801515811461129f57600080fd5b6000602082840312156112da57600080fd5b5051919050565b6000815180845260005b81811015611307576020818501810151868301820152016112eb565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600063ffffffff808716835261ffff861660208401528085166040840152506080606083015261137860808301846112e1565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061126060608301846112e1565b8381526060602082015260006113d06060830185611204565b905082604083015294935050505056fea164736f6c6343000813000a",
}
var VRFV2PlusWrapperConsumerExampleABI = VRFV2PlusWrapperConsumerExampleMetaData.ABI
diff --git a/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer/vrfv2plus_wrapper_load_test_consumer.go b/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer/vrfv2plus_wrapper_load_test_consumer.go
index 20936e51f07..2c79ee7244b 100644
--- a/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer/vrfv2plus_wrapper_load_test_consumer.go
+++ b/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer/vrfv2plus_wrapper_load_test_consumer.go
@@ -32,7 +32,7 @@ var (
var VRFV2PlusWrapperLoadTestConsumerMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfV2PlusWrapper\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyVRFWrapperCanFulfill\",\"type\":\"error\"},{\"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\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"WrappedRequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"}],\"name\":\"WrapperRequestMade\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"getRequestBlockTimes\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_vrfV2PlusWrapper\",\"outputs\":[{\"internalType\":\"contractIVRFV2PlusWrapper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"makeRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"makeRequestsNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageFulfillmentInMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestBlockTimes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"native\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_responseCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
- Bin: "0x60c0604052600060045560006005556103e76006553480156200002157600080fd5b506040516200204638038062002046833981016040819052620000449162000205565b33806000836000819050806001600160a01b0316631c4695f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200008d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b3919062000205565b6001600160a01b0390811660805290811660a052831690506200011d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001505762000150816200015a565b5050505062000237565b336001600160a01b03821603620001b45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000114565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200021857600080fd5b81516001600160a01b03811681146200023057600080fd5b9392505050565b60805160a051611db1620002956000396000818161033a015281816105f8015281816112e6015281816113910152818161143b015281816115af015261161e0152600081816104940152818161079f01526113550152611db16000f3fe6080604052600436106101795760003560e01c8063958cccb7116100cb578063d826f88f1161007f578063e76d516811610059578063e76d516814610485578063f1765962146104b8578063f2fde38b146104d857600080fd5b8063d826f88f14610427578063d8a4676f1461043c578063dc1670db1461046f57600080fd5b8063a168fa89116100b0578063a168fa891461035c578063afacbf9c146103f1578063b1e217491461041157600080fd5b8063958cccb7146102f35780639ed0868d1461032857600080fd5b8063737144bc1161012d5780637a8042bd116101075780637a8042bd1461026757806384276d81146102875780638da5cb5b146102a757600080fd5b8063737144bc1461022657806374dba1241461023c57806379ba50971461025257600080fd5b80631757f11c1161015e5780631757f11c146101d85780631fe543e3146101ee578063557d2e921461021057600080fd5b80630b2634861461018557806312065fe0146101bb57600080fd5b3661018057005b600080fd5b34801561019157600080fd5b506101a56101a0366004611858565b6104f8565b6040516101b2919061187a565b60405180910390f35b3480156101c757600080fd5b50475b6040519081526020016101b2565b3480156101e457600080fd5b506101ca60055481565b3480156101fa57600080fd5b5061020e6102093660046118f3565b6105f6565b005b34801561021c57600080fd5b506101ca60035481565b34801561023257600080fd5b506101ca60045481565b34801561024857600080fd5b506101ca60065481565b34801561025e57600080fd5b5061020e610698565b34801561027357600080fd5b5061020e6102823660046119db565b610795565b34801561029357600080fd5b5061020e6102a23660046119db565b610892565b3480156102b357600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b2565b3480156102ff57600080fd5b5061031361030e3660046119db565b610964565b60405163ffffffff90911681526020016101b2565b34801561033457600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b34801561036857600080fd5b506103ba6103773660046119db565b600a602052600090815260409020805460018201546003830154600484015460058501546006860154600790960154949560ff9485169593949293919290911687565b604080519788529515156020880152948601939093526060850191909152608084015260a0830152151560c082015260e0016101b2565b3480156103fd57600080fd5b5061020e61040c366004611a1f565b61099e565b34801561041d57600080fd5b506101ca60075481565b34801561043357600080fd5b5061020e610b85565b34801561044857600080fd5b5061045c6104573660046119db565b610baf565b6040516101b29796959493929190611aae565b34801561047b57600080fd5b506101ca60025481565b34801561049157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102ce565b3480156104c457600080fd5b5061020e6104d3366004611a1f565b610d32565b3480156104e457600080fd5b5061020e6104f3366004611af5565b610f11565b606060006105068385611b61565b60085490915081111561051857506008545b60006105248583611b74565b67ffffffffffffffff81111561053c5761053c6118c4565b604051908082528060200260200182016040528015610565578160200160208202803683370190505b509050845b828110156105eb576008818154811061058557610585611b87565b6000918252602090912060088204015460079091166004026101000a900463ffffffff16826105b48884611b74565b815181106105c4576105c4611b87565b63ffffffff90921660209283029190910190910152806105e381611bb6565b91505061056a565b509150505b92915050565b7f00000000000000000000000000000000000000000000000000000000000000003373ffffffffffffffffffffffffffffffffffffffff821614610689576040517f8ba9316e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b6106938383610f25565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610719576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610680565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61079d61115b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6107f860005473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af115801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e9190611bee565b5050565b61089a61115b565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169083908381818185875af1925050503d80600081146108f4576040519150601f19603f3d011682016040523d82523d6000602084013e6108f9565b606091505b505090508061088e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f77697468647261774e6174697665206661696c656400000000000000000000006044820152606401610680565b6008818154811061097457600080fd5b9060005260206000209060089182820401919006600402915054906101000a900463ffffffff1681565b6109a661115b565b60005b8161ffff168161ffff161015610b7e5760006109d56040518060200160405280600015158152506111dc565b90506000806109e688888886611298565b6007829055909250905060006109fa6114d3565b604080516101008101825284815260006020808301828152845183815280830186528486019081524260608601526080850184905260a0850187905260c0850184905260e08501849052898452600a8352949092208351815591516001830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790559251805194955091939092610aa29260028501929101906117d7565b5060608201516003828101919091556080830151600483015560a0830151600583015560c0830151600683015560e090920151600790910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558054906000610b1583611bb6565b9091555050600083815260096020526040908190208290555183907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec490610b5f9085815260200190565b60405180910390a2505050508080610b7690611c10565b9150506109a9565b5050505050565b6000600481905560058190556103e760065560038190556002819055610bad90600890611822565b565b6000818152600a602052604081205481906060908290819081908190610c31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610680565b6000888152600a6020908152604080832081516101008101835281548152600182015460ff16151581850152600282018054845181870281018701865281815292959394860193830182828015610ca757602002820191906000526020600020905b815481526020019060010190808311610c93575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff1615151515815250509050806000015181602001518260400151836060015184608001518560a001518660c00151975097509750975097509750975050919395979092949650565b610d3a61115b565b60005b8161ffff168161ffff161015610b7e576000610d696040518060200160405280600115158152506111dc565b9050600080610d7a88888886611561565b600782905590925090506000610d8e6114d3565b604080516101008101825284815260006020808301828152845183815280830186528486019081524260608601526080850184905260a0850187905260c08501849052600160e086018190528a8552600a84529590932084518155905194810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001695151595909517909455905180519495509193610e3592600285019201906117d7565b5060608201516003828101919091556080830151600483015560a0830151600583015560c0830151600683015560e090920151600790910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558054906000610ea883611bb6565b9091555050600083815260096020526040908190208290555183907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec490610ef29085815260200190565b60405180910390a2505050508080610f0990611c10565b915050610d3d565b610f1961115b565b610f22816116bf565b50565b6000828152600a6020526040902054610f9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610680565b6000610fa46114d3565b60008481526009602052604081205491925090610fc19083611b74565b90506000610fd282620f4240611c31565b9050600554821115610fe45760058290555b6006548210610ff557600654610ff7565b815b600655600254611007578061103a565b600254611015906001611b61565b816002546004546110269190611c31565b6110309190611b61565b61103a9190611c48565b6004556002805490600061104d83611bb6565b90915550506000858152600a60209081526040909120600181810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905585516110a5926002909201918701906117d7565b506000858152600a6020526040908190204260048083019190915560068201869055600880546001810182557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee391810491909101805460079092169092026101000a63ffffffff81810219909216918716021790555490517f6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b9161114c9188918891611c83565b60405180910390a15050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610680565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161121591511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b6040517f4306d35400000000000000000000000000000000000000000000000000000000815263ffffffff85166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634306d35490602401602060405180830381865afa15801561132d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113519190611cac565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea07f000000000000000000000000000000000000000000000000000000000000000083898989896040516020016113c89493929190611d29565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016113f593929190611d66565b6020604051808303816000875af1158015611414573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114389190611bee565b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fc2a88c36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c89190611cac565b915094509492505050565b6000466114df816117b4565b1561155a57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115549190611cac565b91505090565b4391505090565b6040517f4b16093500000000000000000000000000000000000000000000000000000000815263ffffffff85166004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634b16093590602401602060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a9190611cac565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639cfc058e82888888886040518663ffffffff1660e01b815260040161167c9493929190611d29565b60206040518083038185885af115801561169a573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906114c89190611cac565b3373ffffffffffffffffffffffffffffffffffffffff82160361173e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610680565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061a4b18214806117c8575062066eed82145b806105f057505062066eee1490565b828054828255906000526020600020908101928215611812579160200282015b828111156118125782518255916020019190600101906117f7565b5061181e929150611843565b5090565b508054600082556007016008900490600052602060002090810190610f2291905b5b8082111561181e5760008155600101611844565b6000806040838503121561186b57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156118b857835163ffffffff1683529284019291840191600101611896565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561190657600080fd5b8235915060208084013567ffffffffffffffff8082111561192657600080fd5b818601915086601f83011261193a57600080fd5b81358181111561194c5761194c6118c4565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561198f5761198f6118c4565b6040529182528482019250838101850191898311156119ad57600080fd5b938501935b828510156119cb578435845293850193928501926119b2565b8096505050505050509250929050565b6000602082840312156119ed57600080fd5b5035919050565b803563ffffffff81168114611a0857600080fd5b919050565b803561ffff81168114611a0857600080fd5b60008060008060808587031215611a3557600080fd5b611a3e856119f4565b9350611a4c60208601611a0d565b9250611a5a604086016119f4565b9150611a6860608601611a0d565b905092959194509250565b600081518084526020808501945080840160005b83811015611aa357815187529582019590820190600101611a87565b509495945050505050565b878152861515602082015260e060408201526000611acf60e0830188611a73565b90508560608301528460808301528360a08301528260c083015298975050505050505050565b600060208284031215611b0757600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114611b2b57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156105f0576105f0611b32565b818103818111156105f0576105f0611b32565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611be757611be7611b32565b5060010190565b600060208284031215611c0057600080fd5b81518015158114611b2b57600080fd5b600061ffff808316818103611c2757611c27611b32565b6001019392505050565b80820281158282048414176105f0576105f0611b32565b600082611c7e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b838152606060208201526000611c9c6060830185611a73565b9050826040830152949350505050565b600060208284031215611cbe57600080fd5b5051919050565b6000815180845260005b81811015611ceb57602081850181015186830182015201611ccf565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600063ffffffff808716835261ffff8616602084015280851660408401525060806060830152611d5c6080830184611cc5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611d9b6060830184611cc5565b9594505050505056fea164736f6c6343000813000a",
+ Bin: "0x60c0604052600060045560006005556103e76006553480156200002157600080fd5b506040516200205638038062002056833981016040819052620000449162000205565b33806000836000819050806001600160a01b0316631c4695f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200008d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b3919062000205565b6001600160a01b0390811660805290811660a052831690506200011d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001505762000150816200015a565b5050505062000237565b336001600160a01b03821603620001b45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000114565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200021857600080fd5b81516001600160a01b03811681146200023057600080fd5b9392505050565b60805160a051611dc1620002956000396000818161033a015281816105f8015281816112ee0152818161139901528181611443015281816115bf015261162e0152600081816104940152818161079f015261135d0152611dc16000f3fe6080604052600436106101795760003560e01c8063958cccb7116100cb578063d826f88f1161007f578063e76d516811610059578063e76d516814610485578063f1765962146104b8578063f2fde38b146104d857600080fd5b8063d826f88f14610427578063d8a4676f1461043c578063dc1670db1461046f57600080fd5b8063a168fa89116100b0578063a168fa891461035c578063afacbf9c146103f1578063b1e217491461041157600080fd5b8063958cccb7146102f35780639ed0868d1461032857600080fd5b8063737144bc1161012d5780637a8042bd116101075780637a8042bd1461026757806384276d81146102875780638da5cb5b146102a757600080fd5b8063737144bc1461022657806374dba1241461023c57806379ba50971461025257600080fd5b80631757f11c1161015e5780631757f11c146101d85780631fe543e3146101ee578063557d2e921461021057600080fd5b80630b2634861461018557806312065fe0146101bb57600080fd5b3661018057005b600080fd5b34801561019157600080fd5b506101a56101a0366004611868565b6104f8565b6040516101b2919061188a565b60405180910390f35b3480156101c757600080fd5b50475b6040519081526020016101b2565b3480156101e457600080fd5b506101ca60055481565b3480156101fa57600080fd5b5061020e610209366004611903565b6105f6565b005b34801561021c57600080fd5b506101ca60035481565b34801561023257600080fd5b506101ca60045481565b34801561024857600080fd5b506101ca60065481565b34801561025e57600080fd5b5061020e610698565b34801561027357600080fd5b5061020e6102823660046119eb565b610795565b34801561029357600080fd5b5061020e6102a23660046119eb565b610892565b3480156102b357600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b2565b3480156102ff57600080fd5b5061031361030e3660046119eb565b610964565b60405163ffffffff90911681526020016101b2565b34801561033457600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b34801561036857600080fd5b506103ba6103773660046119eb565b600a602052600090815260409020805460018201546003830154600484015460058501546006860154600790960154949560ff9485169593949293919290911687565b604080519788529515156020880152948601939093526060850191909152608084015260a0830152151560c082015260e0016101b2565b3480156103fd57600080fd5b5061020e61040c366004611a2f565b61099e565b34801561041d57600080fd5b506101ca60075481565b34801561043357600080fd5b5061020e610b85565b34801561044857600080fd5b5061045c6104573660046119eb565b610baf565b6040516101b29796959493929190611abe565b34801561047b57600080fd5b506101ca60025481565b34801561049157600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102ce565b3480156104c457600080fd5b5061020e6104d3366004611a2f565b610d32565b3480156104e457600080fd5b5061020e6104f3366004611b05565b610f11565b606060006105068385611b71565b60085490915081111561051857506008545b60006105248583611b84565b67ffffffffffffffff81111561053c5761053c6118d4565b604051908082528060200260200182016040528015610565578160200160208202803683370190505b509050845b828110156105eb576008818154811061058557610585611b97565b6000918252602090912060088204015460079091166004026101000a900463ffffffff16826105b48884611b84565b815181106105c4576105c4611b97565b63ffffffff90921660209283029190910190910152806105e381611bc6565b91505061056a565b509150505b92915050565b7f00000000000000000000000000000000000000000000000000000000000000003373ffffffffffffffffffffffffffffffffffffffff821614610689576040517f8ba9316e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b6106938383610f25565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610719576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610680565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61079d61115b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6107f860005473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af115801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e9190611bfe565b5050565b61089a61115b565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169083908381818185875af1925050503d80600081146108f4576040519150601f19603f3d011682016040523d82523d6000602084013e6108f9565b606091505b505090508061088e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f77697468647261774e6174697665206661696c656400000000000000000000006044820152606401610680565b6008818154811061097457600080fd5b9060005260206000209060089182820401919006600402915054906101000a900463ffffffff1681565b6109a661115b565b60005b8161ffff168161ffff161015610b7e5760006109d56040518060200160405280600015158152506111dc565b90506000806109e688888886611298565b6007829055909250905060006109fa6114db565b604080516101008101825284815260006020808301828152845183815280830186528486019081524260608601526080850184905260a0850187905260c0850184905260e08501849052898452600a8352949092208351815591516001830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790559251805194955091939092610aa29260028501929101906117e7565b5060608201516003828101919091556080830151600483015560a0830151600583015560c0830151600683015560e090920151600790910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558054906000610b1583611bc6565b9091555050600083815260096020526040908190208290555183907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec490610b5f9085815260200190565b60405180910390a2505050508080610b7690611c20565b9150506109a9565b5050505050565b6000600481905560058190556103e760065560038190556002819055610bad90600890611832565b565b6000818152600a602052604081205481906060908290819081908190610c31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610680565b6000888152600a6020908152604080832081516101008101835281548152600182015460ff16151581850152600282018054845181870281018701865281815292959394860193830182828015610ca757602002820191906000526020600020905b815481526020019060010190808311610c93575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff1615151515815250509050806000015181602001518260400151836060015184608001518560a001518660c00151975097509750975097509750975050919395979092949650565b610d3a61115b565b60005b8161ffff168161ffff161015610b7e576000610d696040518060200160405280600115158152506111dc565b9050600080610d7a88888886611569565b600782905590925090506000610d8e6114db565b604080516101008101825284815260006020808301828152845183815280830186528486019081524260608601526080850184905260a0850187905260c08501849052600160e086018190528a8552600a84529590932084518155905194810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001695151595909517909455905180519495509193610e3592600285019201906117e7565b5060608201516003828101919091556080830151600483015560a0830151600583015560c0830151600683015560e090920151600790910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558054906000610ea883611bc6565b9091555050600083815260096020526040908190208290555183907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec490610ef29085815260200190565b60405180910390a2505050508080610f0990611c20565b915050610d3d565b610f1961115b565b610f22816116cf565b50565b6000828152600a6020526040902054610f9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610680565b6000610fa46114db565b60008481526009602052604081205491925090610fc19083611b84565b90506000610fd282620f4240611c41565b9050600554821115610fe45760058290555b6006548210610ff557600654610ff7565b815b600655600254611007578061103a565b600254611015906001611b71565b816002546004546110269190611c41565b6110309190611b71565b61103a9190611c58565b6004556002805490600061104d83611bc6565b90915550506000858152600a60209081526040909120600181810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905585516110a5926002909201918701906117e7565b506000858152600a6020526040908190204260048083019190915560068201869055600880546001810182557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee391810491909101805460079092169092026101000a63ffffffff81810219909216918716021790555490517f6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b9161114c9188918891611c93565b60405180910390a15050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610680565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161121591511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b6040517f27e5c50a00000000000000000000000000000000000000000000000000000000815263ffffffff808616600483015283166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906327e5c50a90604401602060405180830381865afa158015611335573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113599190611cbc565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea07f000000000000000000000000000000000000000000000000000000000000000083898989896040516020016113d09493929190611d39565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016113fd93929190611d76565b6020604051808303816000875af115801561141c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114409190611bfe565b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fc2a88c36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d09190611cbc565b915094509492505050565b6000466114e7816117c4565b1561156257606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155c9190611cbc565b91505090565b4391505090565b6040517f13c34b7f00000000000000000000000000000000000000000000000000000000815263ffffffff808616600483015283166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906313c34b7f90604401602060405180830381865afa158015611606573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162a9190611cbc565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639cfc058e82888888886040518663ffffffff1660e01b815260040161168c9493929190611d39565b60206040518083038185885af11580156116aa573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906114d09190611cbc565b3373ffffffffffffffffffffffffffffffffffffffff82160361174e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610680565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061a4b18214806117d8575062066eed82145b806105f057505062066eee1490565b828054828255906000526020600020908101928215611822579160200282015b82811115611822578251825591602001919060010190611807565b5061182e929150611853565b5090565b508054600082556007016008900490600052602060002090810190610f2291905b5b8082111561182e5760008155600101611854565b6000806040838503121561187b57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156118c857835163ffffffff16835292840192918401916001016118a6565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561191657600080fd5b8235915060208084013567ffffffffffffffff8082111561193657600080fd5b818601915086601f83011261194a57600080fd5b81358181111561195c5761195c6118d4565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561199f5761199f6118d4565b6040529182528482019250838101850191898311156119bd57600080fd5b938501935b828510156119db578435845293850193928501926119c2565b8096505050505050509250929050565b6000602082840312156119fd57600080fd5b5035919050565b803563ffffffff81168114611a1857600080fd5b919050565b803561ffff81168114611a1857600080fd5b60008060008060808587031215611a4557600080fd5b611a4e85611a04565b9350611a5c60208601611a1d565b9250611a6a60408601611a04565b9150611a7860608601611a1d565b905092959194509250565b600081518084526020808501945080840160005b83811015611ab357815187529582019590820190600101611a97565b509495945050505050565b878152861515602082015260e060408201526000611adf60e0830188611a83565b90508560608301528460808301528360a08301528260c083015298975050505050505050565b600060208284031215611b1757600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114611b3b57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156105f0576105f0611b42565b818103818111156105f0576105f0611b42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611bf757611bf7611b42565b5060010190565b600060208284031215611c1057600080fd5b81518015158114611b3b57600080fd5b600061ffff808316818103611c3757611c37611b42565b6001019392505050565b80820281158282048414176105f0576105f0611b42565b600082611c8e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b838152606060208201526000611cac6060830185611a83565b9050826040830152949350505050565b600060208284031215611cce57600080fd5b5051919050565b6000815180845260005b81811015611cfb57602081850181015186830182015201611cdf565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600063ffffffff808716835261ffff8616602084015280851660408401525060806060830152611d6c6080830184611cd5565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611dab6060830184611cd5565b9594505050505056fea164736f6c6343000813000a",
}
var VRFV2PlusWrapperLoadTestConsumerABI = VRFV2PlusWrapperLoadTestConsumerMetaData.ABI
diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt
index 1638038b56b..8299cd5ff15 100644
--- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt
+++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt
@@ -8,13 +8,13 @@ automation_compatible_utils: ../../contracts/solc/v0.8.19/AutomationCompatibleUt
automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e
automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5
automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42
-automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin 20fac1208261e866caa1f3ffc71030f682a96761bebe79e5ecd71186fce86c60
+automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin b42de91c15c7453d8262124e20594819d64a3f23bef8e6db66fa5180d18a8454
automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 2f267fb8467a15c587ce4586ac56069f7229344ad3936430d7c7624c0528a171
-automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 71e1f5b676306de9e2d7edc4f44e87cb18e542337a8c4756f554c4e47d213e5a
+automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 1163ecd34c575cb17ffbc2f88fa175816f36982e91992d940ed435d306b3418c
automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin a6d33dfbbfb0ff253eb59a51f4f6d6d4c22ea5ec95aae52d25d49a312b37a22f
-automation_registry_logic_b_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin 47e52b9cba609322c6996293ff5de64cf3b1c1f2e983ff0fe342beaeabfc7ea4
+automation_registry_logic_b_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin 2d0f45d2087f6f3c8bfa0a16b26a1c8c1d5c64b89859478c609201535c96eeed
automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin de60f69878e9b32a291a001c91fc8636544c2cfbd9b507c8c1a4873b602bfb62
-automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin 172ca6c3a5b3e8f43443ae21435efb98dcb0651b0bb8e7ef25761d4761abe12a
+automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin 2f9db5da86183eaf4f78f726458e5a928d37f7c90c4024923847b25186b644c5
automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 815b17b63f15d26a0274b962eefad98cdee4ec897ead58688bbb8e2470e585f5
automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 8743f6231aaefa3f2a0b2d484258070d506e2d0860690e66890dccc3949edb2e
automation_utils_2_3: ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.abi ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.bin 11e2b481dc9a4d936e3443345d45d2cc571164459d214917b42a8054b295393b
@@ -31,7 +31,7 @@ dummy_protocol_wrapper: ../../contracts/solc/v0.8.16/DummyProtocol/DummyProtocol
gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723
gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8
i_automation_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 9ff7087179f89f9b05964ebc3e71332fce11f1b8e85058f7b16b3bc0dd6fb96b
-i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.bin 16b346a64126554bad0929f49ce020d886cc7203d03ca52c4537daf273b4c369
+i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.bin fbfa3f5d78a357ecb7a1bc597c629ff30d42fedc48ba7f57e1622a6302d36523
i_automation_v21_plus_common: ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.abi ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.bin e8a601ec382c0a2e83c49759de13b0622b5e04e6b95901e96a1e9504329e594c
i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 383611981c86c70522f41b8750719faacc7d7933a22849d5004799ebef3371fa
i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin ee0f150b3afbab2df3d24ff3f4c87851efa635da30db04cd1f70cb4e185a1781
@@ -89,17 +89,17 @@ vrf_load_test_ownerless_consumer: ../../contracts/solc/v0.8.6/VRFLoadTestOwnerle
vrf_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics/VRFV2LoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics/VRFV2LoadTestWithMetrics.bin c9621c52d216a090ff6bbe942f1b75d2bce8658a27323c3789e5e14b523277ee
vrf_log_emitter: ../../contracts/solc/v0.8.19/VRFLogEmitter/VRFLogEmitter.abi ../../contracts/solc/v0.8.19/VRFLogEmitter/VRFLogEmitter.bin 15f491d445ac4d0c712d1cbe4e5054c759b080bf20de7d54bfe2a82cde4dcf06
vrf_malicious_consumer_v2: ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2/VRFMaliciousConsumerV2.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2/VRFMaliciousConsumerV2.bin 9755fa8ffc7f5f0b337d5d413d77b0c9f6cd6f68c31727d49acdf9d4a51bc522
-vrf_malicious_consumer_v2_plus: ../../contracts/solc/v0.8.19/VRFMaliciousConsumerV2Plus/VRFMaliciousConsumerV2Plus.abi ../../contracts/solc/v0.8.19/VRFMaliciousConsumerV2Plus/VRFMaliciousConsumerV2Plus.bin 41e00ab611e1b62589130cbb54e8420bfd31c90d842847ec6d9f991a9fec4027
+vrf_malicious_consumer_v2_plus: ../../contracts/solc/v0.8.19/VRFMaliciousConsumerV2Plus/VRFMaliciousConsumerV2Plus.abi ../../contracts/solc/v0.8.19/VRFMaliciousConsumerV2Plus/VRFMaliciousConsumerV2Plus.bin f6bf81658d3472bb705d28dc4a837097ec93d78c3f786efaa9cd040ada9d3319
vrf_mock_ethlink_aggregator: ../../contracts/solc/v0.8.6/VRFMockETHLINKAggregator/VRFMockETHLINKAggregator.abi ../../contracts/solc/v0.8.6/VRFMockETHLINKAggregator/VRFMockETHLINKAggregator.bin 3657f8c552147eb55d7538fa7d8012c1a983d8c5184610de60600834a72e006b
vrf_owner: ../../contracts/solc/v0.8.6/VRFOwner/VRFOwner.abi ../../contracts/solc/v0.8.6/VRFOwner/VRFOwner.bin eccfae5ee295b5850e22f61240c469f79752b8d9a3bac5d64aec7ac8def2f6cb
vrf_owner_test_consumer: ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer/VRFV2OwnerTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer/VRFV2OwnerTestConsumer.bin 6969de242efe8f366ae4097fc279d9375c8e2d0307aaa322e31f2ce6b8c1909a
vrf_ownerless_consumer_example: ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample/VRFOwnerlessConsumerExample.abi ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample/VRFOwnerlessConsumerExample.bin 9893b3805863273917fb282eed32274e32aa3d5c2a67a911510133e1218132be
vrf_single_consumer_example: ../../contracts/solc/v0.8.6/VRFSingleConsumerExample/VRFSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFSingleConsumerExample/VRFSingleConsumerExample.bin 892a5ed35da2e933f7fd7835cd6f7f70ef3aa63a9c03a22c5b1fd026711b0ece
vrf_v2_consumer_wrapper: ../../contracts/solc/v0.8.6/VRFv2Consumer/VRFv2Consumer.abi ../../contracts/solc/v0.8.6/VRFv2Consumer/VRFv2Consumer.bin 12368b3b5e06392440143a13b94c0ea2f79c4c897becc3b060982559e10ace40
-vrf_v2plus_load_test_with_metrics: ../../contracts/solc/v0.8.19/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.19/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.bin af2452b489f4c252c69ffea48fbd601cd1bff69b2e1ce64b9b596380efaeb824
-vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.19/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.bin 1a6b101ee212da2fab7662dde918453ec6bae862568cff5151daea171583dfc9
-vrf_v2plus_sub_owner: ../../contracts/solc/v0.8.19/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.bin fbe58337e8bc497a26deaec76d7177fe625c60691db89151d62076de0e6bbd75
-vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.19/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.bin 4a7df5b066bc3944622009659828fae35bc39d15cf4d218c1560dbdf39b10de2
+vrf_v2plus_load_test_with_metrics: ../../contracts/solc/v0.8.19/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.19/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.bin 593dbcdcc212fc9ec69fe71684711d112433cc31218fe21305ace9229ac29289
+vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.19/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.bin cfdfb97b1b0801ee778410d54b1f6541395ac01ab592ffd6c3feaf4a3ac3eca2
+vrf_v2plus_sub_owner: ../../contracts/solc/v0.8.19/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.bin 6032a081ad15453e52af1cf37c74a9f77f2a30bc14b2cb35f564eabc4b0b4c2e
+vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.19/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.bin 50429c68bc9e4edcddc4b15d65867bff9ae308314b52ed997e7d5665f0703148
vrfv2_proxy_admin: ../../contracts/solc/v0.8.6/VRFV2ProxyAdmin/VRFV2ProxyAdmin.abi ../../contracts/solc/v0.8.6/VRFV2ProxyAdmin/VRFV2ProxyAdmin.bin 402b1103087ffe1aa598854a8f8b38f8cd3de2e3aaa86369e28017a9157f4980
vrfv2_reverting_example: ../../contracts/solc/v0.8.6/VRFV2RevertingExample/VRFV2RevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2RevertingExample/VRFV2RevertingExample.bin 1ae46f80351d428bd85ba58b9041b2a608a1845300d79a8fed83edf96606de87
vrfv2_transparent_upgradeable_proxy: ../../contracts/solc/v0.8.6/VRFV2TransparentUpgradeableProxy/VRFV2TransparentUpgradeableProxy.abi ../../contracts/solc/v0.8.6/VRFV2TransparentUpgradeableProxy/VRFV2TransparentUpgradeableProxy.bin fe1a8e6852fbd06d91f64315c5cede86d340891f5b5cc981fb5b86563f7eac3f
@@ -108,9 +108,9 @@ vrfv2_wrapper_consumer_example: ../../contracts/solc/v0.8.6/VRFV2WrapperConsumer
vrfv2_wrapper_interface: ../../contracts/solc/v0.8.6/VRFV2WrapperInterface/VRFV2WrapperInterface.abi ../../contracts/solc/v0.8.6/VRFV2WrapperInterface/VRFV2WrapperInterface.bin ff8560169de171a68b360b7438d13863682d07040d984fd0fb096b2379421003
vrfv2_wrapper_load_test_consumer: ../../contracts/solc/v0.8.6/VRFV2WrapperLoadTestConsumer/VRFV2WrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2WrapperLoadTestConsumer/VRFV2WrapperLoadTestConsumer.bin 664ca7fdf4dd65cc183bc25f20708c4b369c3401bba3ee12797a93bcd70138b6
vrfv2plus_client: ../../contracts/solc/v0.8.19/VRFV2PlusClient/VRFV2PlusClient.abi ../../contracts/solc/v0.8.19/VRFV2PlusClient/VRFV2PlusClient.bin 875d2c6f287babe5135cc7f67b6f1b1d8de746143ef6918fcadf044d1892dd2a
-vrfv2plus_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusConsumerExample/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusConsumerExample/VRFV2PlusConsumerExample.bin e25c1981638fb9ea8fdd21600d6954f999bf65b98ba4e4a3f8fb9f7858334e19
+vrfv2plus_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusConsumerExample/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusConsumerExample/VRFV2PlusConsumerExample.bin 5e0bdf21048dd6b405ccaa3d260d7fb6d24fd256094310a5cb149aed68e4f892
vrfv2plus_malicious_migrator: ../../contracts/solc/v0.8.19/VRFV2PlusMaliciousMigrator/VRFV2PlusMaliciousMigrator.abi ../../contracts/solc/v0.8.19/VRFV2PlusMaliciousMigrator/VRFV2PlusMaliciousMigrator.bin 5dff20621fe6ed3bed75fe4b65381b0d4b1f6286ee3571553dbeb57213b53416
-vrfv2plus_reverting_example: ../../contracts/solc/v0.8.19/VRFV2PlusRevertingExample/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusRevertingExample/VRFV2PlusRevertingExample.bin ebc2e96af9bf3aaa8b9cb048f8ecfec9987ee8b90126b740722c6b6427ab128e
-vrfv2plus_wrapper: ../../contracts/solc/v0.8.19/VRFV2PlusWrapper/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper/VRFV2PlusWrapper.bin 199af16342b22086fe4186c438857cd15b7dccbeb06e94f48b293b2237bb4278
-vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.bin 130217ffb341f19d1b3bda27f5c4a10567ac21ac3a49c9933bbdb068e8420177
-vrfv2plus_wrapper_load_test_consumer: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.bin f2880b0469b82ddd4a11aa81ac12916f2912555dfe64829416a583fd82ebf3ab
+vrfv2plus_reverting_example: ../../contracts/solc/v0.8.19/VRFV2PlusRevertingExample/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusRevertingExample/VRFV2PlusRevertingExample.bin 82860e6ed846eaa4a5127b96c8ce4e444138412e9ed0605cfdecb6995436b3af
+vrfv2plus_wrapper: ../../contracts/solc/v0.8.19/VRFV2PlusWrapper/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper/VRFV2PlusWrapper.bin 9d601662c578e5da232f065bde0053a6a03545127e8cac6f8897a78bc0861b3f
+vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.bin 7554bc93b2a60361cdd5611f7802de58deba6257a84d11545993f4aa37bdff02
+vrfv2plus_wrapper_load_test_consumer: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.bin 824cf74f968382efdcbbbc866eef884c13d59295b1f07b6646727ed4c0686c86
diff --git a/core/gethwrappers/go_generate_test.go b/core/gethwrappers/go_generate_test.go
index 52d0f520dd7..a6253cb1a66 100644
--- a/core/gethwrappers/go_generate_test.go
+++ b/core/gethwrappers/go_generate_test.go
@@ -4,6 +4,7 @@ package gethwrappers
import (
"crypto/sha256"
+ "flag"
"fmt"
"os"
"os/exec"
@@ -15,6 +16,7 @@ import (
"github.com/fatih/color"
cutils "github.com/smartcontractkit/chainlink-common/pkg/utils"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/utils"
"github.com/stretchr/testify/assert"
@@ -27,6 +29,7 @@ const compileCommand = "../../contracts/scripts/native_solc_compile_all"
// contract artifacts in contracts/solc with the abi and bytecode stored in the
// contract wrapper
func TestCheckContractHashesFromLastGoGenerate(t *testing.T) {
+ testutils.SkipShort(t, "requires compiled artifacts")
versions, err := ReadVersionsDB()
require.NoError(t, err)
require.NotEmpty(t, versions.GethVersion, `version DB should have a "GETH_VERSION:" line`)
@@ -63,19 +66,13 @@ func isVRFV2Contract(fullpath string) bool {
return strings.Contains(fullpath, "VRFCoordinatorV2")
}
-// rootDir is the local chainlink root working directory
-var rootDir string
-
-func init() { // compute rootDir
- var err error
- thisDir, err := os.Getwd()
- if err != nil {
- panic(err)
- }
- rootDir, err = filepath.Abs(filepath.Join(thisDir, "../.."))
+// getRootDir returns the local chainlink root working directory
+func getRootDir() (string, error) { // compute rootDir
+ wd, err := os.Getwd()
if err != nil {
- panic(err)
+ return "", fmt.Errorf("failed to get working directory: %w", err)
}
+ return filepath.Abs(filepath.Join(wd, "../.."))
}
// compareCurrentCompilerArtifactAgainstRecordsAndSoliditySources checks that
@@ -95,6 +92,8 @@ func compareCurrentCompilerArtifactAgainstRecordsAndSoliditySources(
t *testing.T, versionInfo ContractVersion,
) {
hash := VersionHash(versionInfo.AbiPath, versionInfo.BinaryPath)
+ rootDir, err := getRootDir()
+ require.NoError(t, err)
recompileCommand := fmt.Sprintf("(cd %s/contracts; make wrappers-all)", rootDir)
assert.Equal(t, versionInfo.Hash, hash,
utils.BoxOutput(`compiled %s and/or %s has changed; please rerun
@@ -102,9 +101,17 @@ func compareCurrentCompilerArtifactAgainstRecordsAndSoliditySources(
and commit the changes`, versionInfo.AbiPath, versionInfo.BinaryPath, recompileCommand))
}
+func TestMain(m *testing.M) {
+ flag.Parse()
+ if !testing.Short() {
+ ensureArtifacts()
+ }
+ os.Exit(m.Run())
+}
+
// Ensure that solidity compiler artifacts are present before running this test,
// by compiling them if necessary.
-func init() {
+func ensureArtifacts() {
db, err := versionsDBLineReader()
if err != nil {
panic(err)
diff --git a/core/gethwrappers/keystone/generated/forwarder/forwarder.go b/core/gethwrappers/keystone/generated/forwarder/forwarder.go
index c66e2886793..c8cf31ae869 100644
--- a/core/gethwrappers/keystone/generated/forwarder/forwarder.go
+++ b/core/gethwrappers/keystone/generated/forwarder/forwarder.go
@@ -31,8 +31,8 @@ var (
)
var KeystoneForwarderMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"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\":\"workflowExecutionId\",\"type\":\"bytes32\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"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\"}]",
- Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610c12806101576000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063c0965dc311610050578063c0965dc314610108578063e6b714581461012b578063f2fde38b1461016157600080fd5b8063181f5a771461007757806379ba5097146100bf5780638da5cb5b146100c9575b600080fd5b604080518082018252601781527f4b657973746f6e65466f7277617264657220312e302e30000000000000000000602082015290516100b69190610827565b60405180910390f35b6100c7610174565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b6565b61011b6101163660046108bc565b610276565b60405190151581526020016100b6565b6100e3610139366004610998565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6100c761016f3660046109b1565b61058e565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60025460009060ff16156102b6576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556044841161034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c69642064617461206c656e6774680000000000000000000000000060448201526064016101f1565b600061035a85600481896109d3565b8101906103679190610a2c565b8051602082012090915060005b848110156104655760008060006103e289898681811061039657610396610afb565b90506020028101906103a89190610b2a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506105a292505050565b925092509250600060018683868660405160008152602001604052604051610426949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610448573d6000803e3d6000fd5b5086955061045d9450859350610b9692505050565b915050610374565b5060008061047284610630565b600081815260036020526040902054919350915073ffffffffffffffffffffffffffffffffffffffff16156104ae57600094505050505061055d565b6000808b73ffffffffffffffffffffffffffffffffffffffff168b8b6040516104d8929190610bf5565b6000604051808303816000865af19150503d8060008114610515576040519150601f19603f3d011682016040523d82523d6000602084013e61051a565b606091505b5050506000928352505060036020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055506001925050505b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905595945050505050565b6105966106af565b61059f81610732565b50565b60008060008351604114610612576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f696e76616c6964207369676e6174757265206c656e677468000000000000000060448201526064016101f1565b50505060208101516040820151606090920151909260009190911a90565b600080604083511161069e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f696e76616c6964207265706f7274206c656e677468000000000000000000000060448201526064016101f1565b505060208101516040909101519091565b60005473ffffffffffffffffffffffffffffffffffffffff163314610730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016101f1565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036107b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016101f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208083528351808285015260005b8181101561085457858101830151858201604001528201610838565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108b757600080fd5b919050565b6000806000806000606086880312156108d457600080fd5b6108dd86610893565b9450602086013567ffffffffffffffff808211156108fa57600080fd5b818801915088601f83011261090e57600080fd5b81358181111561091d57600080fd5b89602082850101111561092f57600080fd5b60208301965080955050604088013591508082111561094d57600080fd5b818801915088601f83011261096157600080fd5b81358181111561097057600080fd5b8960208260051b850101111561098557600080fd5b9699959850939650602001949392505050565b6000602082840312156109aa57600080fd5b5035919050565b6000602082840312156109c357600080fd5b6109cc82610893565b9392505050565b600080858511156109e357600080fd5b838611156109f057600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610a3e57600080fd5b813567ffffffffffffffff80821115610a5657600080fd5b818401915084601f830112610a6a57600080fd5b813581811115610a7c57610a7c6109fd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610ac257610ac26109fd565b81604052828152876020848701011115610adb57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610b5f57600080fd5b83018035915067ffffffffffffffff821115610b7a57600080fd5b602001915036819003821315610b8f57600080fd5b9250929050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610bee577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b818382376000910190815291905056fea164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"InvalidData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"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\":\"workflowExecutionId\",\"type\":\"bytes32\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"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\"}]",
+ Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610c5f806101576000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063c0965dc311610050578063c0965dc314610108578063e6b714581461012b578063f2fde38b1461016157600080fd5b8063181f5a771461007757806379ba5097146100bf5780638da5cb5b146100c9575b600080fd5b604080518082018252601781527f4b657973746f6e65466f7277617264657220312e302e30000000000000000000602082015290516100b69190610806565b60405180910390f35b6100c7610174565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b6565b61011b61011636600461089b565b610276565b60405190151581526020016100b6565b6100e3610139366004610977565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6100c761016f366004610990565b61056d565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60025460009060ff16156102b6576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556102ed604060046109e1565b84101561032a5784846040517f2a62609b0000000000000000000000000000000000000000000000000000000081526004016101f19291906109fa565b60006103398560048189610a47565b8101906103469190610aa0565b8051602082012090915060005b848110156104445760008060006103c189898681811061037557610375610b6f565b90506020028101906103879190610b9e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061058192505050565b925092509250600060018683868660405160008152602001604052604051610405949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610427573d6000803e3d6000fd5b5086955061043c9450859350610c0a92505050565b915050610353565b506000806104518461060f565b600081815260036020526040902054919350915073ffffffffffffffffffffffffffffffffffffffff161561048d57600094505050505061053c565b6000808b73ffffffffffffffffffffffffffffffffffffffff168b8b6040516104b7929190610c42565b6000604051808303816000865af19150503d80600081146104f4576040519150601f19603f3d011682016040523d82523d6000602084013e6104f9565b606091505b5050506000928352505060036020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055506001925050505b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905595945050505050565b61057561068e565b61057e81610711565b50565b600080600083516041146105f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f696e76616c6964207369676e6174757265206c656e677468000000000000000060448201526064016101f1565b50505060208101516040820151606090920151909260009190911a90565b600080604083511161067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f696e76616c6964207265706f7274206c656e677468000000000000000000000060448201526064016101f1565b505060208101516040909101519091565b60005473ffffffffffffffffffffffffffffffffffffffff16331461070f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016101f1565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610790576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016101f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208083528351808285015260005b8181101561083357858101830151858201604001528201610817565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089657600080fd5b919050565b6000806000806000606086880312156108b357600080fd5b6108bc86610872565b9450602086013567ffffffffffffffff808211156108d957600080fd5b818801915088601f8301126108ed57600080fd5b8135818111156108fc57600080fd5b89602082850101111561090e57600080fd5b60208301965080955050604088013591508082111561092c57600080fd5b818801915088601f83011261094057600080fd5b81358181111561094f57600080fd5b8960208260051b850101111561096457600080fd5b9699959850939650602001949392505050565b60006020828403121561098957600080fd5b5035919050565b6000602082840312156109a257600080fd5b6109ab82610872565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156109f4576109f46109b2565b92915050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60008085851115610a5757600080fd5b83861115610a6457600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ab257600080fd5b813567ffffffffffffffff80821115610aca57600080fd5b818401915084601f830112610ade57600080fd5b813581811115610af057610af0610a71565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610b3657610b36610a71565b81604052828152876020848701011115610b4f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610bd357600080fd5b83018035915067ffffffffffffffff821115610bee57600080fd5b602001915036819003821315610c0357600080fd5b9250929050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610c3b57610c3b6109b2565b5060010190565b818382376000910190815291905056fea164736f6c6343000813000a",
}
var KeystoneForwarderABI = KeystoneForwarderMetaData.ABI
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 b9d8bfbfefc..8b1c830405d 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,3 +1,3 @@
GETH_VERSION: 1.13.8
-forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin 4886b538e1fdc8aaf860901de36269e0c35acfd3e6eb190654d693ff9dbd4b6d
+forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3
ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2
diff --git a/core/gethwrappers/ocr2vrf/generated/dkg/dkg.go b/core/gethwrappers/ocr2vrf/generated/dkg/dkg.go
deleted file mode 100644
index 7a18b7f55bd..00000000000
--- a/core/gethwrappers/ocr2vrf/generated/dkg/dkg.go
+++ /dev/null
@@ -1,1274 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package dkg
-
-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
-)
-
-type KeyDataStructKeyData struct {
- PublicKey []byte
- Hashes [][32]byte
-}
-
-var DKGMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"CalldataLengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedNumSignatures\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expectedLength\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"InvalidOnchainConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"KeyIDCopyFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"numFaultyOracles\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"}],\"name\":\"NumberOfFaultyOraclesTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"repeatedSignerAddress\",\"type\":\"address\"}],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"repeatedTransmitterAddress\",\"type\":\"address\"}],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numTransmitters\",\"type\":\"uint256\"}],\"name\":\"SignersTransmittersMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"maxOracles\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"providedOracles\",\"type\":\"uint256\"}],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractDKGClient\",\"name\":\"client\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"errorData\",\"type\":\"bytes\"}],\"name\":\"DKGClientError\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashes\",\"type\":\"bytes32[]\"}],\"indexed\":false,\"internalType\":\"structKeyDataStruct.KeyData\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"KeyGenerated\",\"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\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyID\",\"type\":\"bytes32\"},{\"internalType\":\"contractDKGClient\",\"name\":\"clientAddress\",\"type\":\"address\"}],\"name\":\"addClient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_keyID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_configDigest\",\"type\":\"bytes32\"}],\"name\":\"getKey\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"structKeyDataStruct.KeyData\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyID\",\"type\":\"bytes32\"},{\"internalType\":\"contractDKGClient\",\"name\":\"clientAddress\",\"type\":\"address\"}],\"name\":\"removeClient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]",
- Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a5565b50505062000150565b336001600160a01b03821603620000ff5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612b8080620001606000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638da5cb5b11610081578063c3105a6b1161005b578063c3105a6b146101db578063e3d0e712146101fb578063f2fde38b1461020e57600080fd5b80638da5cb5b14610176578063afcb95d71461019e578063b1dc65a4146101c857600080fd5b806379ba5097116100b257806379ba50971461012b5780637bf1ffc51461013357806381ff70481461014657600080fd5b8063181f5a77146100ce5780635429a79e14610116575b600080fd5b604080518082018252600981527f444b4720302e302e3100000000000000000000000000000000000000000000006020820152905161010d9190611fc8565b60405180910390f35b610129610124366004612004565b610221565b005b6101296104b0565b610129610141366004612004565b6105b2565b6007546005546040805163ffffffff8085168252640100000000909404909316602084015282015260600161010d565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010d565b6005546004546040805160008152602081019390935263ffffffff9091169082015260600161010d565b6101296101d6366004612080565b61061e565b6101ee6101e9366004612165565b610761565b60405161010d9190612187565b6101296102093660046123dd565b61088a565b61012961021c3660046124aa565b6111ec565b610229611200565b60008281526002602090815260408083208054825181850281018501909352808352919290919083018282801561029657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161026b575b505050505090506000815167ffffffffffffffff8111156102b9576102b961220d565b6040519080825280602002602001820160405280156102e2578160200160208202803683370190505b5090506000805b83518110156103b9578473ffffffffffffffffffffffffffffffffffffffff1684828151811061031b5761031b6124c7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161461039957848361034a8484612525565b8151811061035a5761035a6124c7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506103a7565b816103a381612538565b9250505b806103b181612538565b9150506102e9565b5060008184516103c99190612525565b67ffffffffffffffff8111156103e1576103e161220d565b60405190808252806020026020018201604052801561040a578160200160208202803683370190505b50905060005b82855161041d9190612525565b81101561048757838181518110610436576104366124c7565b6020026020010151828281518110610450576104506124c7565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061047f81612538565b915050610410565b50600086815260026020908152604090912082516104a792840190611e61565b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6105ba611200565b600091825260026020908152604083208054600181018255908452922090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60005a604080516020601f8b018190048102820181019092528981529192508a3591818c01359161066e9184918491908e908e908190840183828082843760009201919091525061128392505050565b6040805183815263ffffffff600884901c1660208201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260055480825260065460ff808216602085015261010090910416928201929092529083146107215780516040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091526024810184905260440161052d565b61072f8b8b8b8b8b8b611512565b6107408c8c8c8c8c8c8c8c89611599565b50505063ffffffff811061075657610756612570565b505050505050505050565b604080518082019091526060808252602082015260008381526003602090815260408083208584529091529081902081518083019092528054829082906107a79061259f565b80601f01602080910402602001604051908101604052809291908181526020018280546107d39061259f565b80156108205780601f106107f557610100808354040283529160200191610820565b820191906000526020600020905b81548152906001019060200180831161080357829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561087857602002820191906000526020600020905b815481526020019060010190808311610864575b50505050508152505090505b92915050565b8551855185601f8311156108d4576040517f809fc428000000000000000000000000000000000000000000000000000000008152601f60048201526024810184905260440161052d565b818314610917576040517f988a0804000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260440161052d565b6109228160036125f2565b60ff168311610969576040517ffda9db7800000000000000000000000000000000000000000000000000000000815260ff821660048201526024810184905260440161052d565b8060ff166000036109a6576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109ae611200565b6040805160c0810182528a8152602081018a905260ff8916918101919091526060810187905267ffffffffffffffff8616608082015260a081018590525b60095415610ba157600954600090610a0690600190612525565b9050600060098281548110610a1d57610a1d6124c7565b6000918252602082200154600a805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110610a5757610a576124c7565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526008909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600980549192509080610ad757610ad7612615565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055600a805480610b4057610b40612615565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055506109ec915050565b60005b81515181101561101c5760006008600084600001518481518110610bca57610bca6124c7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115610c1457610c14612644565b14610c84578151805182908110610c2d57610c2d6124c7565b60200260200101516040517f7451f83e00000000000000000000000000000000000000000000000000000000815260040161052d919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040805180820190915260ff82168152600160208201528251805160089160009185908110610cb557610cb56124c7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610d5657610d56612644565b021790555060009150610d669050565b6008600084602001518481518110610d8057610d806124c7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115610dca57610dca612644565b14610e3c5781602001518181518110610de557610de56124c7565b60200260200101516040517fe8d2989900000000000000000000000000000000000000000000000000000000815260040161052d919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040805180820190915260ff821681526020810160028152506008600084602001518481518110610e6f57610e6f6124c7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610f1057610f10612644565b021790555050825180516009925083908110610f2e57610f2e6124c7565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558201518051600a919083908110610faa57610faa6124c7565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061101481612538565b915050610ba4565b506040810151600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600754640100000000900463ffffffff1661106c611a2f565b6007805463ffffffff928316640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff8216811783556001936000926110bd928692908116911617612673565b92506101000a81548163ffffffff021916908363ffffffff160217905550600061111e4630600760009054906101000a900463ffffffff1663ffffffff1686600001518760200151886040015189606001518a608001518b60a00151611ac6565b6005819055835180516006805460ff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9092169190911790556007546020860151604080880151606089015160808a015160a08b015193519798507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05976111c3978b978b9763ffffffff9091169691959094909390929091906126e1565b60405180910390a16111de8360400151846060015183611b71565b505050505050505050505050565b6111f4611200565b6111fd81611d6c565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611281576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161052d565b565b60006060808380602001905181019061129c9190612777565b60408051808201825283815260208082018490526000868152600282528381208054855181850281018501909652808652979a509598509396509094929391929083018282801561132357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116112f8575b5050505050905060005b815181101561144d57818181518110611348576113486124c7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663bf2732c7846040518263ffffffff1660e01b81526004016113889190612187565b600060405180830381600087803b1580156113a257600080fd5b505af19250505080156113b3575060015b61143b573d8080156113e1576040519150601f19603f3d011682016040523d82523d6000602084013e6113e6565b606091505b507f116391732f5df106193bda7cedf1728f3b07b62f6cdcdd611c9eeec44efcae5483838151811061141a5761141a6124c7565b602002602001015182604051611431929190612875565b60405180910390a1505b8061144581612538565b91505061132d565b5060008581526003602090815260408083208b845290915290208251839190819061147890826128fb565b5060208281015180516114919260018501920190611eeb565b5090505084887fc8db841f5b2231ccf7190311f440aa197b161e369f3b40b023508160cc555656846040516114c69190612187565b60405180910390a350506004805460089690961c63ffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909616959095179094555050505050565b600061151f826020612a15565b61152a856020612a15565b61153688610144612a2c565b6115409190612a2c565b61154a9190612a2c565b611555906000612a2c565b90503681146104a7576040517ff7b94f0a0000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161052d565b60006002826020015183604001516115b19190612a3f565b6115bb9190612a58565b6115c6906001612a3f565b60408051600180825281830190925260ff929092169250600091906020820181803683370190505090508160f81b81600081518110611607576116076124c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535086821415806116455750868514155b1561168d576040517fe307bd5700000000000000000000000000000000000000000000000000000000815260048101839052602481018890526044810186905260640161052d565b3360009081526008602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156116d0576116d0612644565b60028111156116e1576116e1612644565b90525090506002816020015160028111156116fe576116fe612644565b1415806117465750600a816000015160ff1681548110611720576117206124c7565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b1561177f576040517f2d0f0c0f00000000000000000000000000000000000000000000000000000000815233600482015260240161052d565b50505060008888604051611794929190612aa1565b6040519081900381206117ab918c90602001612ab1565b6040516020818303038152906040528051906020012090506117cb611f26565b604080518082019091526000808252602082015260005b88811015611a20576000600185888460208110611801576118016124c7565b61180e91901a601b612a3f565b8d8d86818110611820576118206124c7565b905060200201358c8c87818110611839576118396124c7565b9050602002013560405160008152602001604052604051611876949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611898573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526008602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561191857611918612644565b600281111561192957611929612644565b905250925060018360200151600281111561194657611946612644565b14611995576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161052d565b8251849060ff16601f81106119ac576119ac6124c7565b6020020151156119e8576040517f21cf3b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184846000015160ff16601f8110611a0357611a036124c7565b911515602090920201525080611a1881612538565b9150506117e2565b50505050505050505050505050565b60004661a4b1811480611a44575062066eed81145b15611abf57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab99190612ac5565b91505090565b4391505090565b6000808a8a8a8a8a8a8a8a8a604051602001611aea99989796959493929190612ade565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6000808351602014611bbc5783516040517f1625adfe00000000000000000000000000000000000000000000000000000000815260206004820152602481019190915260440161052d565b60208401519150808203611bfc576040517faf5e77d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152606080825260208201526000838152600360209081526040808320878452909152902081518291908190611c3a90826128fb565b506020828101518051611c539260018501920190611eeb565b505050600083815260026020908152604080832080548251818502810185019093528083529192909190830182828015611cc357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c98575b5050505050905060005b8151811015611d6257818181518110611ce857611ce86124c7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166355e487496040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611d3757600080fd5b505af1158015611d4b573d6000803e3d6000fd5b505050508080611d5a90612538565b915050611ccd565b5050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161052d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215611edb579160200282015b82811115611edb57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190611e81565b50611ee7929150611f45565b5090565b828054828255906000526020600020908101928215611edb579160200282015b82811115611edb578251825591602001919060010190611f0b565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115611ee75760008155600101611f46565b60005b83811015611f75578181015183820152602001611f5d565b50506000910152565b60008151808452611f96816020860160208601611f5a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611fdb6020830184611f7e565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146111fd57600080fd5b6000806040838503121561201757600080fd5b82359150602083013561202981611fe2565b809150509250929050565b60008083601f84011261204657600080fd5b50813567ffffffffffffffff81111561205e57600080fd5b6020830191508360208260051b850101111561207957600080fd5b9250929050565b60008060008060008060008060e0898b03121561209c57600080fd5b606089018a8111156120ad57600080fd5b8998503567ffffffffffffffff808211156120c757600080fd5b818b0191508b601f8301126120db57600080fd5b8135818111156120ea57600080fd5b8c60208285010111156120fc57600080fd5b6020830199508098505060808b013591508082111561211a57600080fd5b6121268c838d01612034565b909750955060a08b013591508082111561213f57600080fd5b5061214c8b828c01612034565b999c989b50969995989497949560c00135949350505050565b6000806040838503121561217857600080fd5b50508035926020909101359150565b6000602080835283516040828501526121a36060850182611f7e565b858301518582037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040870152805180835290840192506000918401905b8083101561220257835182529284019260019290920191908401906121e2565b509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156122835761228361220d565b604052919050565b600067ffffffffffffffff8211156122a5576122a561220d565b5060051b60200190565b600082601f8301126122c057600080fd5b813560206122d56122d08361228b565b61223c565b82815260059290921b840181019181810190868411156122f457600080fd5b8286015b8481101561220257803561230b81611fe2565b83529183019183016122f8565b803560ff8116811461232957600080fd5b919050565b600067ffffffffffffffff8211156123485761234861220d565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261238557600080fd5b81356123936122d08261232e565b8181528460208386010111156123a857600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff8116811461232957600080fd5b60008060008060008060c087890312156123f657600080fd5b863567ffffffffffffffff8082111561240e57600080fd5b61241a8a838b016122af565b9750602089013591508082111561243057600080fd5b61243c8a838b016122af565b965061244a60408a01612318565b9550606089013591508082111561246057600080fd5b61246c8a838b01612374565b945061247a60808a016123c5565b935060a089013591508082111561249057600080fd5b5061249d89828a01612374565b9150509295509295509295565b6000602082840312156124bc57600080fd5b8135611fdb81611fe2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610884576108846124f6565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612569576125696124f6565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600181811c908216806125b357607f821691505b6020821081036125ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60ff818116838216029081169081811461260e5761260e6124f6565b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b63ffffffff81811683821601908082111561260e5761260e6124f6565b600081518084526020808501945080840160005b838110156126d657815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016126a4565b509495945050505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526127118184018a612690565b905082810360808401526127258189612690565b905060ff871660a084015282810360c08401526127428187611f7e565b905067ffffffffffffffff851660e08401528281036101008401526127678185611f7e565b9c9b505050505050505050505050565b60008060006060848603121561278c57600080fd5b8351925060208085015167ffffffffffffffff808211156127ac57600080fd5b818701915087601f8301126127c057600080fd5b81516127ce6122d08261232e565b81815289858386010111156127e257600080fd5b6127f182868301878701611f5a565b60408901519096509250508082111561280957600080fd5b508501601f8101871361281b57600080fd5b80516128296122d08261228b565b81815260059190911b8201830190838101908983111561284857600080fd5b928401925b828410156128665783518252928401929084019061284d565b80955050505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006128a46040830184611f7e565b949350505050565b601f8211156128f657600081815260208120601f850160051c810160208610156128d35750805b601f850160051c820191505b818110156128f2578281556001016128df565b5050505b505050565b815167ffffffffffffffff8111156129155761291561220d565b61292981612923845461259f565b846128ac565b602080601f83116001811461297c57600084156129465750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556128f2565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156129c9578886015182559484019460019091019084016129aa565b5085821015612a0557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8082028115828204841417610884576108846124f6565b80820180821115610884576108846124f6565b60ff8181168382160190811115610884576108846124f6565b600060ff831680612a92577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612ad757600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152612b258285018b612690565b91508382036080850152612b39828a612690565b915060ff881660a085015283820360c0850152612b568288611f7e565b90861660e085015283810361010085015290506127678185611f7e56fea164736f6c6343000813000a",
-}
-
-var DKGABI = DKGMetaData.ABI
-
-var DKGBin = DKGMetaData.Bin
-
-func DeployDKG(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *DKG, error) {
- parsed, err := DKGMetaData.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(DKGBin), backend)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &DKG{DKGCaller: DKGCaller{contract: contract}, DKGTransactor: DKGTransactor{contract: contract}, DKGFilterer: DKGFilterer{contract: contract}}, nil
-}
-
-type DKG struct {
- address common.Address
- abi abi.ABI
- DKGCaller
- DKGTransactor
- DKGFilterer
-}
-
-type DKGCaller struct {
- contract *bind.BoundContract
-}
-
-type DKGTransactor struct {
- contract *bind.BoundContract
-}
-
-type DKGFilterer struct {
- contract *bind.BoundContract
-}
-
-type DKGSession struct {
- Contract *DKG
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type DKGCallerSession struct {
- Contract *DKGCaller
- CallOpts bind.CallOpts
-}
-
-type DKGTransactorSession struct {
- Contract *DKGTransactor
- TransactOpts bind.TransactOpts
-}
-
-type DKGRaw struct {
- Contract *DKG
-}
-
-type DKGCallerRaw struct {
- Contract *DKGCaller
-}
-
-type DKGTransactorRaw struct {
- Contract *DKGTransactor
-}
-
-func NewDKG(address common.Address, backend bind.ContractBackend) (*DKG, error) {
- abi, err := abi.JSON(strings.NewReader(DKGABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindDKG(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &DKG{address: address, abi: abi, DKGCaller: DKGCaller{contract: contract}, DKGTransactor: DKGTransactor{contract: contract}, DKGFilterer: DKGFilterer{contract: contract}}, nil
-}
-
-func NewDKGCaller(address common.Address, caller bind.ContractCaller) (*DKGCaller, error) {
- contract, err := bindDKG(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &DKGCaller{contract: contract}, nil
-}
-
-func NewDKGTransactor(address common.Address, transactor bind.ContractTransactor) (*DKGTransactor, error) {
- contract, err := bindDKG(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &DKGTransactor{contract: contract}, nil
-}
-
-func NewDKGFilterer(address common.Address, filterer bind.ContractFilterer) (*DKGFilterer, error) {
- contract, err := bindDKG(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &DKGFilterer{contract: contract}, nil
-}
-
-func bindDKG(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := DKGMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_DKG *DKGRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _DKG.Contract.DKGCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_DKG *DKGRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _DKG.Contract.DKGTransactor.contract.Transfer(opts)
-}
-
-func (_DKG *DKGRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _DKG.Contract.DKGTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_DKG *DKGCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _DKG.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_DKG *DKGTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _DKG.Contract.contract.Transfer(opts)
-}
-
-func (_DKG *DKGTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _DKG.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_DKG *DKGCaller) GetKey(opts *bind.CallOpts, _keyID [32]byte, _configDigest [32]byte) (KeyDataStructKeyData, error) {
- var out []interface{}
- err := _DKG.contract.Call(opts, &out, "getKey", _keyID, _configDigest)
-
- if err != nil {
- return *new(KeyDataStructKeyData), err
- }
-
- out0 := *abi.ConvertType(out[0], new(KeyDataStructKeyData)).(*KeyDataStructKeyData)
-
- return out0, err
-
-}
-
-func (_DKG *DKGSession) GetKey(_keyID [32]byte, _configDigest [32]byte) (KeyDataStructKeyData, error) {
- return _DKG.Contract.GetKey(&_DKG.CallOpts, _keyID, _configDigest)
-}
-
-func (_DKG *DKGCallerSession) GetKey(_keyID [32]byte, _configDigest [32]byte) (KeyDataStructKeyData, error) {
- return _DKG.Contract.GetKey(&_DKG.CallOpts, _keyID, _configDigest)
-}
-
-func (_DKG *DKGCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails,
-
- error) {
- var out []interface{}
- err := _DKG.contract.Call(opts, &out, "latestConfigDetails")
-
- outstruct := new(LatestConfigDetails)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32)
- outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32)
- outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte)
-
- return *outstruct, err
-
-}
-
-func (_DKG *DKGSession) LatestConfigDetails() (LatestConfigDetails,
-
- error) {
- return _DKG.Contract.LatestConfigDetails(&_DKG.CallOpts)
-}
-
-func (_DKG *DKGCallerSession) LatestConfigDetails() (LatestConfigDetails,
-
- error) {
- return _DKG.Contract.LatestConfigDetails(&_DKG.CallOpts)
-}
-
-func (_DKG *DKGCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch,
-
- error) {
- var out []interface{}
- err := _DKG.contract.Call(opts, &out, "latestConfigDigestAndEpoch")
-
- outstruct := new(LatestConfigDigestAndEpoch)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool)
- outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte)
- outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32)
-
- return *outstruct, err
-
-}
-
-func (_DKG *DKGSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch,
-
- error) {
- return _DKG.Contract.LatestConfigDigestAndEpoch(&_DKG.CallOpts)
-}
-
-func (_DKG *DKGCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch,
-
- error) {
- return _DKG.Contract.LatestConfigDigestAndEpoch(&_DKG.CallOpts)
-}
-
-func (_DKG *DKGCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _DKG.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 (_DKG *DKGSession) Owner() (common.Address, error) {
- return _DKG.Contract.Owner(&_DKG.CallOpts)
-}
-
-func (_DKG *DKGCallerSession) Owner() (common.Address, error) {
- return _DKG.Contract.Owner(&_DKG.CallOpts)
-}
-
-func (_DKG *DKGCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) {
- var out []interface{}
- err := _DKG.contract.Call(opts, &out, "typeAndVersion")
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_DKG *DKGSession) TypeAndVersion() (string, error) {
- return _DKG.Contract.TypeAndVersion(&_DKG.CallOpts)
-}
-
-func (_DKG *DKGCallerSession) TypeAndVersion() (string, error) {
- return _DKG.Contract.TypeAndVersion(&_DKG.CallOpts)
-}
-
-func (_DKG *DKGTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _DKG.contract.Transact(opts, "acceptOwnership")
-}
-
-func (_DKG *DKGSession) AcceptOwnership() (*types.Transaction, error) {
- return _DKG.Contract.AcceptOwnership(&_DKG.TransactOpts)
-}
-
-func (_DKG *DKGTransactorSession) AcceptOwnership() (*types.Transaction, error) {
- return _DKG.Contract.AcceptOwnership(&_DKG.TransactOpts)
-}
-
-func (_DKG *DKGTransactor) AddClient(opts *bind.TransactOpts, keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) {
- return _DKG.contract.Transact(opts, "addClient", keyID, clientAddress)
-}
-
-func (_DKG *DKGSession) AddClient(keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) {
- return _DKG.Contract.AddClient(&_DKG.TransactOpts, keyID, clientAddress)
-}
-
-func (_DKG *DKGTransactorSession) AddClient(keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) {
- return _DKG.Contract.AddClient(&_DKG.TransactOpts, keyID, clientAddress)
-}
-
-func (_DKG *DKGTransactor) RemoveClient(opts *bind.TransactOpts, keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) {
- return _DKG.contract.Transact(opts, "removeClient", keyID, clientAddress)
-}
-
-func (_DKG *DKGSession) RemoveClient(keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) {
- return _DKG.Contract.RemoveClient(&_DKG.TransactOpts, keyID, clientAddress)
-}
-
-func (_DKG *DKGTransactorSession) RemoveClient(keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) {
- return _DKG.Contract.RemoveClient(&_DKG.TransactOpts, keyID, clientAddress)
-}
-
-func (_DKG *DKGTransactor) SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) {
- return _DKG.contract.Transact(opts, "setConfig", _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig)
-}
-
-func (_DKG *DKGSession) SetConfig(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) {
- return _DKG.Contract.SetConfig(&_DKG.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig)
-}
-
-func (_DKG *DKGTransactorSession) SetConfig(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) {
- return _DKG.Contract.SetConfig(&_DKG.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig)
-}
-
-func (_DKG *DKGTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
- return _DKG.contract.Transact(opts, "transferOwnership", to)
-}
-
-func (_DKG *DKGSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _DKG.Contract.TransferOwnership(&_DKG.TransactOpts, to)
-}
-
-func (_DKG *DKGTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _DKG.Contract.TransferOwnership(&_DKG.TransactOpts, to)
-}
-
-func (_DKG *DKGTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) {
- return _DKG.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs)
-}
-
-func (_DKG *DKGSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) {
- return _DKG.Contract.Transmit(&_DKG.TransactOpts, reportContext, report, rs, ss, rawVs)
-}
-
-func (_DKG *DKGTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) {
- return _DKG.Contract.Transmit(&_DKG.TransactOpts, reportContext, report, rs, ss, rawVs)
-}
-
-type DKGConfigSetIterator struct {
- Event *DKGConfigSet
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *DKGConfigSetIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(DKGConfigSet)
- 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(DKGConfigSet)
- 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 *DKGConfigSetIterator) Error() error {
- return it.fail
-}
-
-func (it *DKGConfigSetIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type DKGConfigSet struct {
- PreviousConfigBlockNumber uint32
- ConfigDigest [32]byte
- ConfigCount uint64
- Signers []common.Address
- Transmitters []common.Address
- F uint8
- OnchainConfig []byte
- OffchainConfigVersion uint64
- OffchainConfig []byte
- Raw types.Log
-}
-
-func (_DKG *DKGFilterer) FilterConfigSet(opts *bind.FilterOpts) (*DKGConfigSetIterator, error) {
-
- logs, sub, err := _DKG.contract.FilterLogs(opts, "ConfigSet")
- if err != nil {
- return nil, err
- }
- return &DKGConfigSetIterator{contract: _DKG.contract, event: "ConfigSet", logs: logs, sub: sub}, nil
-}
-
-func (_DKG *DKGFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *DKGConfigSet) (event.Subscription, error) {
-
- logs, sub, err := _DKG.contract.WatchLogs(opts, "ConfigSet")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(DKGConfigSet)
- if err := _DKG.contract.UnpackLog(event, "ConfigSet", 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 (_DKG *DKGFilterer) ParseConfigSet(log types.Log) (*DKGConfigSet, error) {
- event := new(DKGConfigSet)
- if err := _DKG.contract.UnpackLog(event, "ConfigSet", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type DKGDKGClientErrorIterator struct {
- Event *DKGDKGClientError
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *DKGDKGClientErrorIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(DKGDKGClientError)
- 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(DKGDKGClientError)
- 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 *DKGDKGClientErrorIterator) Error() error {
- return it.fail
-}
-
-func (it *DKGDKGClientErrorIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type DKGDKGClientError struct {
- Client common.Address
- ErrorData []byte
- Raw types.Log
-}
-
-func (_DKG *DKGFilterer) FilterDKGClientError(opts *bind.FilterOpts) (*DKGDKGClientErrorIterator, error) {
-
- logs, sub, err := _DKG.contract.FilterLogs(opts, "DKGClientError")
- if err != nil {
- return nil, err
- }
- return &DKGDKGClientErrorIterator{contract: _DKG.contract, event: "DKGClientError", logs: logs, sub: sub}, nil
-}
-
-func (_DKG *DKGFilterer) WatchDKGClientError(opts *bind.WatchOpts, sink chan<- *DKGDKGClientError) (event.Subscription, error) {
-
- logs, sub, err := _DKG.contract.WatchLogs(opts, "DKGClientError")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(DKGDKGClientError)
- if err := _DKG.contract.UnpackLog(event, "DKGClientError", 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 (_DKG *DKGFilterer) ParseDKGClientError(log types.Log) (*DKGDKGClientError, error) {
- event := new(DKGDKGClientError)
- if err := _DKG.contract.UnpackLog(event, "DKGClientError", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type DKGKeyGeneratedIterator struct {
- Event *DKGKeyGenerated
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *DKGKeyGeneratedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(DKGKeyGenerated)
- 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(DKGKeyGenerated)
- 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 *DKGKeyGeneratedIterator) Error() error {
- return it.fail
-}
-
-func (it *DKGKeyGeneratedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type DKGKeyGenerated struct {
- ConfigDigest [32]byte
- KeyID [32]byte
- Key KeyDataStructKeyData
- Raw types.Log
-}
-
-func (_DKG *DKGFilterer) FilterKeyGenerated(opts *bind.FilterOpts, configDigest [][32]byte, keyID [][32]byte) (*DKGKeyGeneratedIterator, error) {
-
- var configDigestRule []interface{}
- for _, configDigestItem := range configDigest {
- configDigestRule = append(configDigestRule, configDigestItem)
- }
- var keyIDRule []interface{}
- for _, keyIDItem := range keyID {
- keyIDRule = append(keyIDRule, keyIDItem)
- }
-
- logs, sub, err := _DKG.contract.FilterLogs(opts, "KeyGenerated", configDigestRule, keyIDRule)
- if err != nil {
- return nil, err
- }
- return &DKGKeyGeneratedIterator{contract: _DKG.contract, event: "KeyGenerated", logs: logs, sub: sub}, nil
-}
-
-func (_DKG *DKGFilterer) WatchKeyGenerated(opts *bind.WatchOpts, sink chan<- *DKGKeyGenerated, configDigest [][32]byte, keyID [][32]byte) (event.Subscription, error) {
-
- var configDigestRule []interface{}
- for _, configDigestItem := range configDigest {
- configDigestRule = append(configDigestRule, configDigestItem)
- }
- var keyIDRule []interface{}
- for _, keyIDItem := range keyID {
- keyIDRule = append(keyIDRule, keyIDItem)
- }
-
- logs, sub, err := _DKG.contract.WatchLogs(opts, "KeyGenerated", configDigestRule, keyIDRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(DKGKeyGenerated)
- if err := _DKG.contract.UnpackLog(event, "KeyGenerated", 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 (_DKG *DKGFilterer) ParseKeyGenerated(log types.Log) (*DKGKeyGenerated, error) {
- event := new(DKGKeyGenerated)
- if err := _DKG.contract.UnpackLog(event, "KeyGenerated", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type DKGOwnershipTransferRequestedIterator struct {
- Event *DKGOwnershipTransferRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *DKGOwnershipTransferRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(DKGOwnershipTransferRequested)
- 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(DKGOwnershipTransferRequested)
- 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 *DKGOwnershipTransferRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *DKGOwnershipTransferRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type DKGOwnershipTransferRequested struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_DKG *DKGFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DKGOwnershipTransferRequestedIterator, 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 := _DKG.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &DKGOwnershipTransferRequestedIterator{contract: _DKG.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
-}
-
-func (_DKG *DKGFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DKGOwnershipTransferRequested, 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 := _DKG.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(DKGOwnershipTransferRequested)
- if err := _DKG.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 (_DKG *DKGFilterer) ParseOwnershipTransferRequested(log types.Log) (*DKGOwnershipTransferRequested, error) {
- event := new(DKGOwnershipTransferRequested)
- if err := _DKG.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type DKGOwnershipTransferredIterator struct {
- Event *DKGOwnershipTransferred
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *DKGOwnershipTransferredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(DKGOwnershipTransferred)
- 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(DKGOwnershipTransferred)
- 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 *DKGOwnershipTransferredIterator) Error() error {
- return it.fail
-}
-
-func (it *DKGOwnershipTransferredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type DKGOwnershipTransferred struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_DKG *DKGFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DKGOwnershipTransferredIterator, 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 := _DKG.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &DKGOwnershipTransferredIterator{contract: _DKG.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
-}
-
-func (_DKG *DKGFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DKGOwnershipTransferred, 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 := _DKG.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(DKGOwnershipTransferred)
- if err := _DKG.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 (_DKG *DKGFilterer) ParseOwnershipTransferred(log types.Log) (*DKGOwnershipTransferred, error) {
- event := new(DKGOwnershipTransferred)
- if err := _DKG.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type DKGTransmittedIterator struct {
- Event *DKGTransmitted
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *DKGTransmittedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(DKGTransmitted)
- 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(DKGTransmitted)
- 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 *DKGTransmittedIterator) Error() error {
- return it.fail
-}
-
-func (it *DKGTransmittedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type DKGTransmitted struct {
- ConfigDigest [32]byte
- Epoch uint32
- Raw types.Log
-}
-
-func (_DKG *DKGFilterer) FilterTransmitted(opts *bind.FilterOpts) (*DKGTransmittedIterator, error) {
-
- logs, sub, err := _DKG.contract.FilterLogs(opts, "Transmitted")
- if err != nil {
- return nil, err
- }
- return &DKGTransmittedIterator{contract: _DKG.contract, event: "Transmitted", logs: logs, sub: sub}, nil
-}
-
-func (_DKG *DKGFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *DKGTransmitted) (event.Subscription, error) {
-
- logs, sub, err := _DKG.contract.WatchLogs(opts, "Transmitted")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(DKGTransmitted)
- if err := _DKG.contract.UnpackLog(event, "Transmitted", 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 (_DKG *DKGFilterer) ParseTransmitted(log types.Log) (*DKGTransmitted, error) {
- event := new(DKGTransmitted)
- if err := _DKG.contract.UnpackLog(event, "Transmitted", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type LatestConfigDetails struct {
- ConfigCount uint32
- BlockNumber uint32
- ConfigDigest [32]byte
-}
-type LatestConfigDigestAndEpoch struct {
- ScanLogs bool
- ConfigDigest [32]byte
- Epoch uint32
-}
-
-func (_DKG *DKG) ParseLog(log types.Log) (generated.AbigenLog, error) {
- switch log.Topics[0] {
- case _DKG.abi.Events["ConfigSet"].ID:
- return _DKG.ParseConfigSet(log)
- case _DKG.abi.Events["DKGClientError"].ID:
- return _DKG.ParseDKGClientError(log)
- case _DKG.abi.Events["KeyGenerated"].ID:
- return _DKG.ParseKeyGenerated(log)
- case _DKG.abi.Events["OwnershipTransferRequested"].ID:
- return _DKG.ParseOwnershipTransferRequested(log)
- case _DKG.abi.Events["OwnershipTransferred"].ID:
- return _DKG.ParseOwnershipTransferred(log)
- case _DKG.abi.Events["Transmitted"].ID:
- return _DKG.ParseTransmitted(log)
-
- default:
- return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
- }
-}
-
-func (DKGConfigSet) Topic() common.Hash {
- return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05")
-}
-
-func (DKGDKGClientError) Topic() common.Hash {
- return common.HexToHash("0x116391732f5df106193bda7cedf1728f3b07b62f6cdcdd611c9eeec44efcae54")
-}
-
-func (DKGKeyGenerated) Topic() common.Hash {
- return common.HexToHash("0xc8db841f5b2231ccf7190311f440aa197b161e369f3b40b023508160cc555656")
-}
-
-func (DKGOwnershipTransferRequested) Topic() common.Hash {
- return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
-}
-
-func (DKGOwnershipTransferred) Topic() common.Hash {
- return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
-}
-
-func (DKGTransmitted) Topic() common.Hash {
- return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62")
-}
-
-func (_DKG *DKG) Address() common.Address {
- return _DKG.address
-}
-
-type DKGInterface interface {
- GetKey(opts *bind.CallOpts, _keyID [32]byte, _configDigest [32]byte) (KeyDataStructKeyData, error)
-
- LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails,
-
- error)
-
- LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch,
-
- error)
-
- Owner(opts *bind.CallOpts) (common.Address, error)
-
- TypeAndVersion(opts *bind.CallOpts) (string, error)
-
- AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
-
- AddClient(opts *bind.TransactOpts, keyID [32]byte, clientAddress common.Address) (*types.Transaction, error)
-
- RemoveClient(opts *bind.TransactOpts, keyID [32]byte, clientAddress common.Address) (*types.Transaction, error)
-
- SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error)
-
- TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
-
- Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error)
-
- FilterConfigSet(opts *bind.FilterOpts) (*DKGConfigSetIterator, error)
-
- WatchConfigSet(opts *bind.WatchOpts, sink chan<- *DKGConfigSet) (event.Subscription, error)
-
- ParseConfigSet(log types.Log) (*DKGConfigSet, error)
-
- FilterDKGClientError(opts *bind.FilterOpts) (*DKGDKGClientErrorIterator, error)
-
- WatchDKGClientError(opts *bind.WatchOpts, sink chan<- *DKGDKGClientError) (event.Subscription, error)
-
- ParseDKGClientError(log types.Log) (*DKGDKGClientError, error)
-
- FilterKeyGenerated(opts *bind.FilterOpts, configDigest [][32]byte, keyID [][32]byte) (*DKGKeyGeneratedIterator, error)
-
- WatchKeyGenerated(opts *bind.WatchOpts, sink chan<- *DKGKeyGenerated, configDigest [][32]byte, keyID [][32]byte) (event.Subscription, error)
-
- ParseKeyGenerated(log types.Log) (*DKGKeyGenerated, error)
-
- FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DKGOwnershipTransferRequestedIterator, error)
-
- WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DKGOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferRequested(log types.Log) (*DKGOwnershipTransferRequested, error)
-
- FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DKGOwnershipTransferredIterator, error)
-
- WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DKGOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferred(log types.Log) (*DKGOwnershipTransferred, error)
-
- FilterTransmitted(opts *bind.FilterOpts) (*DKGTransmittedIterator, error)
-
- WatchTransmitted(opts *bind.WatchOpts, sink chan<- *DKGTransmitted) (event.Subscription, error)
-
- ParseTransmitted(log types.Log) (*DKGTransmitted, error)
-
- ParseLog(log types.Log) (generated.AbigenLog, error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer/load_test_beacon_consumer.go b/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer/load_test_beacon_consumer.go
deleted file mode 100644
index 32bf1e66219..00000000000
--- a/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer/load_test_beacon_consumer.go
+++ /dev/null
@@ -1,1422 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package load_test_beacon_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 LoadTestBeaconVRFConsumerMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"shouldFail\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"beaconPeriodBlocks\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"MustBeCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeOwnerOrCoordinator\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorUpdated\",\"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\":[],\"name\":\"fail\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"reqID\",\"type\":\"uint256\"}],\"name\":\"getFulfillmentDurationByRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"reqID\",\"type\":\"uint256\"}],\"name\":\"getRawFulfillmentDurationByRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_beaconPeriodBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingRequests\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"requestHeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_ReceivedRandomnessByRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_arguments\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageFulfillmentInMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_fulfillmentDurationInBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_mostRecentRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_myBeaconRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"slotNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_rawFulfillmentDurationInBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestIDs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestOutputHeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"\",\"type\":\"uint24\"}],\"name\":\"s_requestsIDs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_resetCounter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalFulfilled\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalRequests\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"shouldFail\",\"type\":\"bool\"}],\"name\":\"setFail\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"reqId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"height\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"delay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"}],\"name\":\"storeBeaconRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"testRedeemRandomness\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelayArg\",\"type\":\"uint24\"}],\"name\":\"testRequestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"}],\"name\":\"testRequestRandomnessFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelayArg\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"batchSize\",\"type\":\"uint256\"}],\"name\":\"testRequestRandomnessFulfillmentBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60806040526000600d556000600e556103e7600f556000601055600060115560006012553480156200003057600080fd5b5060405162001f6138038062001f618339810160408190526200005391620001d0565b828282823380600081620000ae5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000e157620000e18162000125565b5050600280546001600160a01b0319166001600160a01b03939093169290921790915550600b805460ff191692151592909217909155600c55506200022792505050565b336001600160a01b038216036200017f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a5565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080600060608486031215620001e657600080fd5b83516001600160a01b0381168114620001fe57600080fd5b602085015190935080151581146200021557600080fd5b80925050604084015190509250925092565b611d2a80620002376000396000f3fe608060405234801561001057600080fd5b50600436106102775760003560e01c806379ba509711610160578063d0705f04116100d8578063f2fde38b1161008c578063f6eaffc811610071578063f6eaffc8146105bc578063fc7fea37146105cf578063ffe97ca4146105d857600080fd5b8063f2fde38b1461057e578063f371829b1461059157600080fd5b8063d826f88f116100bd578063d826f88f1461055a578063ea7502ab14610562578063f08c5daa1461057557600080fd5b8063d0705f0414610534578063d21ea8fd1461054757600080fd5b80638ea981171161012f578063a9cc471811610114578063a9cc4718146104fb578063c6d6130114610518578063cd0593df1461052b57600080fd5b80638ea98117146104a95780639d769402146104bc57600080fd5b806379ba5097146104675780638866c6bd1461046f5780638d0e3165146104785780638da5cb5b1461048157600080fd5b80635a947873116101f35780636df57cc3116101c2578063737144bc116101a7578063737144bc1461044057806374dba124146104495780637716cdaa1461045257600080fd5b80636df57cc314610400578063706da1ca1461041357600080fd5b80635a947873146103b05780635f15cccc146103c3578063601201d3146103ee578063689b77ab146103f757600080fd5b80632b1a21301161024a578063341867a21161022f578063341867a21461035b578063353e0f60146103705780634a0aee291461039b57600080fd5b80632b1a21301461031d5780632fe8fa311461033057600080fd5b80631591950a1461027c5780631757f11c146102ba578063195e0d75146102c35780631e87f20e146102f0575b600080fd5b6102a761028a366004611503565b601560209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6102a7600e5481565b6102a76102d1366004611525565b6012546000908152601860209081526040808320938352929052205490565b6102a76102fe366004611525565b6012546000908152601760209081526040808320938352929052205490565b6102a761032b366004611503565b61068b565b6102a761033e366004611503565b601760209081526000928352604080842090915290825290205481565b61036e610369366004611503565b6106bc565b005b6102a761037e366004611503565b601660209081526000928352604080842090915290825290205481565b6103a36107b1565b6040516102b1919061153e565b6103a36103be3660046116cc565b6108c1565b6102a76103d136600461174d565b600460209081526000928352604080842090915290825290205481565b6102a760115481565b6102a760085481565b61036e61040e366004611779565b610a1f565b6009546104279067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016102b1565b6102a7600d5481565b6102a7600f5481565b61045a610b5a565b6040516102b19190611823565b61036e610be8565b6102a760105481565b6102a760135481565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b1565b61036e6104b736600461183d565b610cea565b61036e6104ca366004611873565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600b546105089060ff1681565b60405190151581526020016102b1565b6102a7610526366004611895565b610dd0565b6102a7600c5481565b6102a7610542366004611503565b610eda565b61036e6105553660046118f5565b610ef6565b61036e610f57565b6102a76105703660046119be565b610f8d565b6102a7600a5481565b61036e61058c36600461183d565b61109d565b6102a761059f366004611503565b601860209081526000928352604080842090915290825290205481565b6102a76105ca366004611525565b6110b1565b6102a760125481565b6106416105e6366004611525565b60056020526000908152604090205463ffffffff811690640100000000810462ffffff1690670100000000000000810461ffff16906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1684565b6040805163ffffffff909516855262ffffff909316602085015261ffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff1660608201526080016102b1565b601460205281600052604060002081815481106106a757600080fd5b90600052602060002001600091509150505481565b60025460408051602081018252600080825291517facfc6cdd000000000000000000000000000000000000000000000000000000008152919273ffffffffffffffffffffffffffffffffffffffff169163acfc6cdd916107229187918791600401611a37565b6000604051808303816000875af1158015610741573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526107879190810190611a5f565b600083815260066020908152604090912082519293506107ab9290918401906114a3565b50505050565b6012546000908152601460205260408120546060919067ffffffffffffffff8111156107df576107df6115c0565b604051908082528060200260200182016040528015610808578160200160208202803683370190505b5090506000805b6012546000908152601460205260409020548110156108b957601254600090815260146020526040812080548390811061084b5761084b611af0565b600091825260208083209091015460125483526017825260408084208285529092529082205490925090036108a6578084848151811061088d5761088d611af0565b6020908102919091010152826108a281611b4e565b9350505b50806108b181611b4e565b91505061080f565b508152919050565b606060008267ffffffffffffffff8111156108de576108de6115c0565b604051908082528060200260200182016040528015610907578160200160208202803683370190505b5090506000600c546109176110d2565b6109219190611bb5565b9050600081600c546109316110d2565b61093b9190611bc9565b6109459190611be2565b905060005b85811015610a105760006109618c8c8c8c8c610f8d565b60108054919250600061097383611b4e565b90915550506012546000908152601560209081526040808320848452909152902083905561099f6110d2565b60128054600090815260166020908152604080832086845282528083209490945591548152601482529182208054600181018255908352912001819055845181908690849081106109f2576109f2611af0565b60209081029190910101525080610a0881611b4e565b91505061094a565b50919998505050505050505050565b600083815260046020908152604080832062ffffff861684529091528120859055600c54610a4d9085611bf5565b6040805160808101825263ffffffff928316815262ffffff958616602080830191825261ffff968716838501908152306060850190815260009b8c526005909252939099209151825491519351995173ffffffffffffffffffffffffffffffffffffffff166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff9a90971667010000000000000002999099167fffffff00000000000000000000000000000000000000000000ffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009091169890931697909717919091171692909217179092555050565b60078054610b6790611c09565b80601f0160208091040260200160405190810160405280929190818152602001828054610b9390611c09565b8015610be05780601f10610bb557610100808354040283529160200191610be0565b820191906000526020600020905b815481529060010190602001808311610bc357829003601f168201915b505050505081565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610d2a575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610d61576040517fd4e06fd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fc258faa9a17ddfdf4130b4acff63a289202e7d5f9e42f366add65368575486bc90600090a250565b600080600c54610dde6110d2565b610de89190611bb5565b9050600081600c54610df86110d2565b610e029190611bc9565b610e0c9190611be2565b60025460408051602081018252600080825291517f4ffac83a000000000000000000000000000000000000000000000000000000008152939450909273ffffffffffffffffffffffffffffffffffffffff90921691634ffac83a91610e7a918a918c918b9190600401611c5c565b6020604051808303816000875af1158015610e99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ebd9190611c94565b9050610ecb8183878a610a1f565b60088190559695505050505050565b600660205281600052604060002081815481106106a757600080fd5b60025473ffffffffffffffffffffffffffffffffffffffff163314610f47576040517f66bf9c7200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f52838383611169565b505050565b6000600d819055600e8190556103e7600f556010819055601181905560138190556012805491610f8683611b4e565b9190505550565b600080600c54610f9b6110d2565b610fa59190611bb5565b9050600081600c54610fb56110d2565b610fbf9190611bc9565b610fc99190611be2565b60025460408051602081018252600080825291517fdb972c8b000000000000000000000000000000000000000000000000000000008152939450909273ffffffffffffffffffffffffffffffffffffffff9092169163db972c8b9161103b918d918d918d918d918d9190600401611cad565b6020604051808303816000875af115801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e9190611c94565b905061108c8183898b610a1f565b600881905598975050505050505050565b6110a561132b565b6110ae816113ae565b50565b600381815481106110c157600080fd5b600091825260209091200154905081565b60004661a4b18114806110e7575062066eed81145b1561116257606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611138573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115c9190611c94565b91505090565b4391505090565b600b5460ff16156111d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f206661696c656420696e2066756c66696c6c52616e646f6d576f7264730000006044820152606401610c65565b600083815260066020908152604090912083516111f5928501906114a3565b50601254600090815260156020908152604080832086845290915281205461121b6110d2565b6112259190611be2565b60125460009081526016602090815260408083208884529091528120549192509061124e6110d2565b6112589190611be2565b9050600061126983620f4240611d06565b9050600e5483111561128057600e83905560138690555b600f54831061129157600f54611293565b825b600f556011546112a357806112d6565b6011546112b1906001611bc9565b81601154600d546112c29190611d06565b6112cc9190611bc9565b6112d69190611bf5565b600d55601180549060006112e983611b4e565b90915550506012805460009081526017602090815260408083208a84528252808320969096559154815260188252848120978152969052509320929092555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c65565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361142d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c65565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8280548282559060005260206000209081019282156114de579160200282015b828111156114de5782518255916020019190600101906114c3565b506114ea9291506114ee565b5090565b5b808211156114ea57600081556001016114ef565b6000806040838503121561151657600080fd5b50508035926020909101359150565b60006020828403121561153757600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156115765783518352928401929184019160010161155a565b50909695505050505050565b803561ffff8116811461159457600080fd5b919050565b803562ffffff8116811461159457600080fd5b803563ffffffff8116811461159457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611636576116366115c0565b604052919050565b600082601f83011261164f57600080fd5b813567ffffffffffffffff811115611669576116696115c0565b61169a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016115ef565b8181528460208386010111156116af57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156116e557600080fd5b863595506116f560208801611582565b945061170360408801611599565b9350611711606088016115ac565b9250608087013567ffffffffffffffff81111561172d57600080fd5b61173989828a0161163e565b92505060a087013590509295509295509295565b6000806040838503121561176057600080fd5b8235915061177060208401611599565b90509250929050565b6000806000806080858703121561178f57600080fd5b84359350602085013592506117a660408601611599565b91506117b460608601611582565b905092959194509250565b6000815180845260005b818110156117e5576020818501810151868301820152016117c9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061183660208301846117bf565b9392505050565b60006020828403121561184f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461183657600080fd5b60006020828403121561188557600080fd5b8135801515811461183657600080fd5b6000806000606084860312156118aa57600080fd5b6118b384611582565b9250602084013591506118c860408501611599565b90509250925092565b600067ffffffffffffffff8211156118eb576118eb6115c0565b5060051b60200190565b60008060006060848603121561190a57600080fd5b8335925060208085013567ffffffffffffffff8082111561192a57600080fd5b818701915087601f83011261193e57600080fd5b813561195161194c826118d1565b6115ef565b81815260059190911b8301840190848101908a83111561197057600080fd5b938501935b8285101561198e57843582529385019390850190611975565b9650505060408701359250808311156119a657600080fd5b50506119b48682870161163e565b9150509250925092565b600080600080600060a086880312156119d657600080fd5b853594506119e660208701611582565b93506119f460408701611599565b9250611a02606087016115ac565b9150608086013567ffffffffffffffff811115611a1e57600080fd5b611a2a8882890161163e565b9150509295509295909350565b838152826020820152606060408201526000611a5660608301846117bf565b95945050505050565b60006020808385031215611a7257600080fd5b825167ffffffffffffffff811115611a8957600080fd5b8301601f81018513611a9a57600080fd5b8051611aa861194c826118d1565b81815260059190911b82018301908381019087831115611ac757600080fd5b928401925b82841015611ae557835182529284019290840190611acc565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b7f57611b7f611b1f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611bc457611bc4611b86565b500690565b80820180821115611bdc57611bdc611b1f565b92915050565b81810381811115611bdc57611bdc611b1f565b600082611c0457611c04611b86565b500490565b600181811c90821680611c1d57607f821691505b602082108103611c56577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b84815261ffff8416602082015262ffffff83166040820152608060608201526000611c8a60808301846117bf565b9695505050505050565b600060208284031215611ca657600080fd5b5051919050565b86815261ffff8616602082015262ffffff8516604082015263ffffffff8416606082015260c060808201526000611ce760c08301856117bf565b82810360a0840152611cf981856117bf565b9998505050505050505050565b8082028115828204841417611bdc57611bdc611b1f56fea164736f6c6343000813000a",
-}
-
-var LoadTestBeaconVRFConsumerABI = LoadTestBeaconVRFConsumerMetaData.ABI
-
-var LoadTestBeaconVRFConsumerBin = LoadTestBeaconVRFConsumerMetaData.Bin
-
-func DeployLoadTestBeaconVRFConsumer(auth *bind.TransactOpts, backend bind.ContractBackend, coordinator common.Address, shouldFail bool, beaconPeriodBlocks *big.Int) (common.Address, *types.Transaction, *LoadTestBeaconVRFConsumer, error) {
- parsed, err := LoadTestBeaconVRFConsumerMetaData.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(LoadTestBeaconVRFConsumerBin), backend, coordinator, shouldFail, beaconPeriodBlocks)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &LoadTestBeaconVRFConsumer{LoadTestBeaconVRFConsumerCaller: LoadTestBeaconVRFConsumerCaller{contract: contract}, LoadTestBeaconVRFConsumerTransactor: LoadTestBeaconVRFConsumerTransactor{contract: contract}, LoadTestBeaconVRFConsumerFilterer: LoadTestBeaconVRFConsumerFilterer{contract: contract}}, nil
-}
-
-type LoadTestBeaconVRFConsumer struct {
- address common.Address
- abi abi.ABI
- LoadTestBeaconVRFConsumerCaller
- LoadTestBeaconVRFConsumerTransactor
- LoadTestBeaconVRFConsumerFilterer
-}
-
-type LoadTestBeaconVRFConsumerCaller struct {
- contract *bind.BoundContract
-}
-
-type LoadTestBeaconVRFConsumerTransactor struct {
- contract *bind.BoundContract
-}
-
-type LoadTestBeaconVRFConsumerFilterer struct {
- contract *bind.BoundContract
-}
-
-type LoadTestBeaconVRFConsumerSession struct {
- Contract *LoadTestBeaconVRFConsumer
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type LoadTestBeaconVRFConsumerCallerSession struct {
- Contract *LoadTestBeaconVRFConsumerCaller
- CallOpts bind.CallOpts
-}
-
-type LoadTestBeaconVRFConsumerTransactorSession struct {
- Contract *LoadTestBeaconVRFConsumerTransactor
- TransactOpts bind.TransactOpts
-}
-
-type LoadTestBeaconVRFConsumerRaw struct {
- Contract *LoadTestBeaconVRFConsumer
-}
-
-type LoadTestBeaconVRFConsumerCallerRaw struct {
- Contract *LoadTestBeaconVRFConsumerCaller
-}
-
-type LoadTestBeaconVRFConsumerTransactorRaw struct {
- Contract *LoadTestBeaconVRFConsumerTransactor
-}
-
-func NewLoadTestBeaconVRFConsumer(address common.Address, backend bind.ContractBackend) (*LoadTestBeaconVRFConsumer, error) {
- abi, err := abi.JSON(strings.NewReader(LoadTestBeaconVRFConsumerABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindLoadTestBeaconVRFConsumer(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &LoadTestBeaconVRFConsumer{address: address, abi: abi, LoadTestBeaconVRFConsumerCaller: LoadTestBeaconVRFConsumerCaller{contract: contract}, LoadTestBeaconVRFConsumerTransactor: LoadTestBeaconVRFConsumerTransactor{contract: contract}, LoadTestBeaconVRFConsumerFilterer: LoadTestBeaconVRFConsumerFilterer{contract: contract}}, nil
-}
-
-func NewLoadTestBeaconVRFConsumerCaller(address common.Address, caller bind.ContractCaller) (*LoadTestBeaconVRFConsumerCaller, error) {
- contract, err := bindLoadTestBeaconVRFConsumer(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &LoadTestBeaconVRFConsumerCaller{contract: contract}, nil
-}
-
-func NewLoadTestBeaconVRFConsumerTransactor(address common.Address, transactor bind.ContractTransactor) (*LoadTestBeaconVRFConsumerTransactor, error) {
- contract, err := bindLoadTestBeaconVRFConsumer(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &LoadTestBeaconVRFConsumerTransactor{contract: contract}, nil
-}
-
-func NewLoadTestBeaconVRFConsumerFilterer(address common.Address, filterer bind.ContractFilterer) (*LoadTestBeaconVRFConsumerFilterer, error) {
- contract, err := bindLoadTestBeaconVRFConsumer(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &LoadTestBeaconVRFConsumerFilterer{contract: contract}, nil
-}
-
-func bindLoadTestBeaconVRFConsumer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := LoadTestBeaconVRFConsumerMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _LoadTestBeaconVRFConsumer.Contract.LoadTestBeaconVRFConsumerCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.LoadTestBeaconVRFConsumerTransactor.contract.Transfer(opts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.LoadTestBeaconVRFConsumerTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _LoadTestBeaconVRFConsumer.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.contract.Transfer(opts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) Fail(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "fail")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) Fail() (bool, error) {
- return _LoadTestBeaconVRFConsumer.Contract.Fail(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) Fail() (bool, error) {
- return _LoadTestBeaconVRFConsumer.Contract.Fail(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) GetFulfillmentDurationByRequestID(opts *bind.CallOpts, reqID *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "getFulfillmentDurationByRequestID", reqID)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) GetFulfillmentDurationByRequestID(reqID *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.GetFulfillmentDurationByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, reqID)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) GetFulfillmentDurationByRequestID(reqID *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.GetFulfillmentDurationByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, reqID)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) GetRawFulfillmentDurationByRequestID(opts *bind.CallOpts, reqID *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "getRawFulfillmentDurationByRequestID", reqID)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) GetRawFulfillmentDurationByRequestID(reqID *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.GetRawFulfillmentDurationByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, reqID)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) GetRawFulfillmentDurationByRequestID(reqID *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.GetRawFulfillmentDurationByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, reqID)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "i_beaconPeriodBlocks")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) IBeaconPeriodBlocks() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.IBeaconPeriodBlocks(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) IBeaconPeriodBlocks() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.IBeaconPeriodBlocks(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.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 (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) Owner() (common.Address, error) {
- return _LoadTestBeaconVRFConsumer.Contract.Owner(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) Owner() (common.Address, error) {
- return _LoadTestBeaconVRFConsumer.Contract.Owner(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) PendingRequests(opts *bind.CallOpts) ([]*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "pendingRequests")
-
- if err != nil {
- return *new([]*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) PendingRequests() ([]*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.PendingRequests(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) PendingRequests() ([]*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.PendingRequests(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) RequestHeights(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "requestHeights", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) RequestHeights(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.RequestHeights(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) RequestHeights(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.RequestHeights(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SReceivedRandomnessByRequestID(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_ReceivedRandomnessByRequestID", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SReceivedRandomnessByRequestID(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SReceivedRandomnessByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SReceivedRandomnessByRequestID(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SReceivedRandomnessByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SArguments(opts *bind.CallOpts) ([]byte, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_arguments")
-
- if err != nil {
- return *new([]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SArguments() ([]byte, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SArguments(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SArguments() ([]byte, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SArguments(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_averageFulfillmentInMillions")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SAverageFulfillmentInMillions() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SAverageFulfillmentInMillions(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SAverageFulfillmentInMillions() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SAverageFulfillmentInMillions(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_fastestFulfillment")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SFastestFulfillment() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SFastestFulfillment(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SFastestFulfillment() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SFastestFulfillment(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SFulfillmentDurationInBlocks(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_fulfillmentDurationInBlocks", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SFulfillmentDurationInBlocks(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SFulfillmentDurationInBlocks(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SFulfillmentDurationInBlocks(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SFulfillmentDurationInBlocks(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SGasAvailable(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_gasAvailable")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SGasAvailable() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SGasAvailable(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SGasAvailable() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SGasAvailable(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SMostRecentRequestID(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_mostRecentRequestID")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SMostRecentRequestID() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SMostRecentRequestID(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SMostRecentRequestID() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SMostRecentRequestID(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SMyBeaconRequests(opts *bind.CallOpts, arg0 *big.Int) (SMyBeaconRequests,
-
- error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_myBeaconRequests", arg0)
-
- outstruct := new(SMyBeaconRequests)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.SlotNumber = *abi.ConvertType(out[0], new(uint32)).(*uint32)
- outstruct.ConfirmationDelay = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
- outstruct.NumWords = *abi.ConvertType(out[2], new(uint16)).(*uint16)
- outstruct.Requester = *abi.ConvertType(out[3], new(common.Address)).(*common.Address)
-
- return *outstruct, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SMyBeaconRequests(arg0 *big.Int) (SMyBeaconRequests,
-
- error) {
- return _LoadTestBeaconVRFConsumer.Contract.SMyBeaconRequests(&_LoadTestBeaconVRFConsumer.CallOpts, arg0)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SMyBeaconRequests(arg0 *big.Int) (SMyBeaconRequests,
-
- error) {
- return _LoadTestBeaconVRFConsumer.Contract.SMyBeaconRequests(&_LoadTestBeaconVRFConsumer.CallOpts, arg0)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRandomWords(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_randomWords", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRandomWords(arg0 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRandomWords(&_LoadTestBeaconVRFConsumer.CallOpts, arg0)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRandomWords(arg0 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRandomWords(&_LoadTestBeaconVRFConsumer.CallOpts, arg0)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRawFulfillmentDurationInBlocks(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_rawFulfillmentDurationInBlocks", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRawFulfillmentDurationInBlocks(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRawFulfillmentDurationInBlocks(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRawFulfillmentDurationInBlocks(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRawFulfillmentDurationInBlocks(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRequestIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_requestIDs", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRequestIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRequestIDs(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRequestIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRequestIDs(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRequestOutputHeights(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_requestOutputHeights", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRequestOutputHeights(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRequestOutputHeights(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRequestOutputHeights(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRequestOutputHeights(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRequestsIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_requestsIDs", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRequestsIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRequestsIDs(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRequestsIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SRequestsIDs(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SResetCounter(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_resetCounter")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SResetCounter() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SResetCounter(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SResetCounter() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SResetCounter(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_slowestFulfillment")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SSlowestFulfillment() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SSlowestFulfillment(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SSlowestFulfillment() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SSlowestFulfillment(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SSlowestRequestID(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_slowestRequestID")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SSlowestRequestID() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SSlowestRequestID(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SSlowestRequestID() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SSlowestRequestID(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SSubId(opts *bind.CallOpts) (uint64, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_subId")
-
- if err != nil {
- return *new(uint64), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SSubId() (uint64, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SSubId(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SSubId() (uint64, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SSubId(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) STotalFulfilled(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_totalFulfilled")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) STotalFulfilled() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.STotalFulfilled(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) STotalFulfilled() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.STotalFulfilled(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) STotalRequests(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_totalRequests")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) STotalRequests() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.STotalRequests(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) STotalRequests() (*big.Int, error) {
- return _LoadTestBeaconVRFConsumer.Contract.STotalRequests(&_LoadTestBeaconVRFConsumer.CallOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "acceptOwnership")
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) AcceptOwnership() (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.AcceptOwnership(&_LoadTestBeaconVRFConsumer.TransactOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) AcceptOwnership() (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.AcceptOwnership(&_LoadTestBeaconVRFConsumer.TransactOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) RawFulfillRandomWords(opts *bind.TransactOpts, requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "rawFulfillRandomWords", requestID, randomWords, arguments)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) RawFulfillRandomWords(requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.RawFulfillRandomWords(&_LoadTestBeaconVRFConsumer.TransactOpts, requestID, randomWords, arguments)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) RawFulfillRandomWords(requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.RawFulfillRandomWords(&_LoadTestBeaconVRFConsumer.TransactOpts, requestID, randomWords, arguments)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) Reset(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "reset")
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) Reset() (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.Reset(&_LoadTestBeaconVRFConsumer.TransactOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) Reset() (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.Reset(&_LoadTestBeaconVRFConsumer.TransactOpts)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) SetCoordinator(opts *bind.TransactOpts, coordinator common.Address) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "setCoordinator", coordinator)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SetCoordinator(coordinator common.Address) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SetCoordinator(&_LoadTestBeaconVRFConsumer.TransactOpts, coordinator)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) SetCoordinator(coordinator common.Address) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SetCoordinator(&_LoadTestBeaconVRFConsumer.TransactOpts, coordinator)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) SetFail(opts *bind.TransactOpts, shouldFail bool) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "setFail", shouldFail)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SetFail(shouldFail bool) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SetFail(&_LoadTestBeaconVRFConsumer.TransactOpts, shouldFail)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) SetFail(shouldFail bool) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.SetFail(&_LoadTestBeaconVRFConsumer.TransactOpts, shouldFail)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) StoreBeaconRequest(opts *bind.TransactOpts, reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "storeBeaconRequest", reqId, height, delay, numWords)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) StoreBeaconRequest(reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.StoreBeaconRequest(&_LoadTestBeaconVRFConsumer.TransactOpts, reqId, height, delay, numWords)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) StoreBeaconRequest(reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.StoreBeaconRequest(&_LoadTestBeaconVRFConsumer.TransactOpts, reqId, height, delay, numWords)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TestRedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "testRedeemRandomness", subID, requestID)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TestRedeemRandomness(subID *big.Int, requestID *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TestRedeemRandomness(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, requestID)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TestRedeemRandomness(subID *big.Int, requestID *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TestRedeemRandomness(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, requestID)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TestRequestRandomness(opts *bind.TransactOpts, numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "testRequestRandomness", numWords, subID, confirmationDelayArg)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TestRequestRandomness(numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomness(&_LoadTestBeaconVRFConsumer.TransactOpts, numWords, subID, confirmationDelayArg)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TestRequestRandomness(numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomness(&_LoadTestBeaconVRFConsumer.TransactOpts, numWords, subID, confirmationDelayArg)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TestRequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "testRequestRandomnessFulfillment", subID, numWords, confDelay, callbackGasLimit, arguments)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TestRequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomnessFulfillment(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TestRequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomnessFulfillment(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TestRequestRandomnessFulfillmentBatch(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confirmationDelayArg *big.Int, callbackGasLimit uint32, arguments []byte, batchSize *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "testRequestRandomnessFulfillmentBatch", subID, numWords, confirmationDelayArg, callbackGasLimit, arguments, batchSize)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TestRequestRandomnessFulfillmentBatch(subID *big.Int, numWords uint16, confirmationDelayArg *big.Int, callbackGasLimit uint32, arguments []byte, batchSize *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomnessFulfillmentBatch(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, numWords, confirmationDelayArg, callbackGasLimit, arguments, batchSize)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TestRequestRandomnessFulfillmentBatch(subID *big.Int, numWords uint16, confirmationDelayArg *big.Int, callbackGasLimit uint32, arguments []byte, batchSize *big.Int) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomnessFulfillmentBatch(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, numWords, confirmationDelayArg, callbackGasLimit, arguments, batchSize)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "transferOwnership", to)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TransferOwnership(&_LoadTestBeaconVRFConsumer.TransactOpts, to)
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _LoadTestBeaconVRFConsumer.Contract.TransferOwnership(&_LoadTestBeaconVRFConsumer.TransactOpts, to)
-}
-
-type LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator struct {
- Event *LoadTestBeaconVRFConsumerCoordinatorUpdated
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(LoadTestBeaconVRFConsumerCoordinatorUpdated)
- 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(LoadTestBeaconVRFConsumerCoordinatorUpdated)
- 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 *LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator) Error() error {
- return it.fail
-}
-
-func (it *LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type LoadTestBeaconVRFConsumerCoordinatorUpdated struct {
- Coordinator common.Address
- Raw types.Log
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) FilterCoordinatorUpdated(opts *bind.FilterOpts, coordinator []common.Address) (*LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator, error) {
-
- var coordinatorRule []interface{}
- for _, coordinatorItem := range coordinator {
- coordinatorRule = append(coordinatorRule, coordinatorItem)
- }
-
- logs, sub, err := _LoadTestBeaconVRFConsumer.contract.FilterLogs(opts, "CoordinatorUpdated", coordinatorRule)
- if err != nil {
- return nil, err
- }
- return &LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator{contract: _LoadTestBeaconVRFConsumer.contract, event: "CoordinatorUpdated", logs: logs, sub: sub}, nil
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) WatchCoordinatorUpdated(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerCoordinatorUpdated, coordinator []common.Address) (event.Subscription, error) {
-
- var coordinatorRule []interface{}
- for _, coordinatorItem := range coordinator {
- coordinatorRule = append(coordinatorRule, coordinatorItem)
- }
-
- logs, sub, err := _LoadTestBeaconVRFConsumer.contract.WatchLogs(opts, "CoordinatorUpdated", coordinatorRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(LoadTestBeaconVRFConsumerCoordinatorUpdated)
- if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "CoordinatorUpdated", 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 (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) ParseCoordinatorUpdated(log types.Log) (*LoadTestBeaconVRFConsumerCoordinatorUpdated, error) {
- event := new(LoadTestBeaconVRFConsumerCoordinatorUpdated)
- if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "CoordinatorUpdated", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator struct {
- Event *LoadTestBeaconVRFConsumerOwnershipTransferRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(LoadTestBeaconVRFConsumerOwnershipTransferRequested)
- 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(LoadTestBeaconVRFConsumerOwnershipTransferRequested)
- 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 *LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type LoadTestBeaconVRFConsumerOwnershipTransferRequested struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator, 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 := _LoadTestBeaconVRFConsumer.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator{contract: _LoadTestBeaconVRFConsumer.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerOwnershipTransferRequested, 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 := _LoadTestBeaconVRFConsumer.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(LoadTestBeaconVRFConsumerOwnershipTransferRequested)
- if err := _LoadTestBeaconVRFConsumer.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 (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) ParseOwnershipTransferRequested(log types.Log) (*LoadTestBeaconVRFConsumerOwnershipTransferRequested, error) {
- event := new(LoadTestBeaconVRFConsumerOwnershipTransferRequested)
- if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type LoadTestBeaconVRFConsumerOwnershipTransferredIterator struct {
- Event *LoadTestBeaconVRFConsumerOwnershipTransferred
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *LoadTestBeaconVRFConsumerOwnershipTransferredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(LoadTestBeaconVRFConsumerOwnershipTransferred)
- 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(LoadTestBeaconVRFConsumerOwnershipTransferred)
- 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 *LoadTestBeaconVRFConsumerOwnershipTransferredIterator) Error() error {
- return it.fail
-}
-
-func (it *LoadTestBeaconVRFConsumerOwnershipTransferredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type LoadTestBeaconVRFConsumerOwnershipTransferred struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LoadTestBeaconVRFConsumerOwnershipTransferredIterator, 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 := _LoadTestBeaconVRFConsumer.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &LoadTestBeaconVRFConsumerOwnershipTransferredIterator{contract: _LoadTestBeaconVRFConsumer.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerOwnershipTransferred, 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 := _LoadTestBeaconVRFConsumer.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(LoadTestBeaconVRFConsumerOwnershipTransferred)
- if err := _LoadTestBeaconVRFConsumer.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 (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) ParseOwnershipTransferred(log types.Log) (*LoadTestBeaconVRFConsumerOwnershipTransferred, error) {
- event := new(LoadTestBeaconVRFConsumerOwnershipTransferred)
- if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type SMyBeaconRequests struct {
- SlotNumber uint32
- ConfirmationDelay *big.Int
- NumWords uint16
- Requester common.Address
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumer) ParseLog(log types.Log) (generated.AbigenLog, error) {
- switch log.Topics[0] {
- case _LoadTestBeaconVRFConsumer.abi.Events["CoordinatorUpdated"].ID:
- return _LoadTestBeaconVRFConsumer.ParseCoordinatorUpdated(log)
- case _LoadTestBeaconVRFConsumer.abi.Events["OwnershipTransferRequested"].ID:
- return _LoadTestBeaconVRFConsumer.ParseOwnershipTransferRequested(log)
- case _LoadTestBeaconVRFConsumer.abi.Events["OwnershipTransferred"].ID:
- return _LoadTestBeaconVRFConsumer.ParseOwnershipTransferred(log)
-
- default:
- return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
- }
-}
-
-func (LoadTestBeaconVRFConsumerCoordinatorUpdated) Topic() common.Hash {
- return common.HexToHash("0xc258faa9a17ddfdf4130b4acff63a289202e7d5f9e42f366add65368575486bc")
-}
-
-func (LoadTestBeaconVRFConsumerOwnershipTransferRequested) Topic() common.Hash {
- return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
-}
-
-func (LoadTestBeaconVRFConsumerOwnershipTransferred) Topic() common.Hash {
- return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
-}
-
-func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumer) Address() common.Address {
- return _LoadTestBeaconVRFConsumer.address
-}
-
-type LoadTestBeaconVRFConsumerInterface interface {
- Fail(opts *bind.CallOpts) (bool, error)
-
- GetFulfillmentDurationByRequestID(opts *bind.CallOpts, reqID *big.Int) (*big.Int, error)
-
- GetRawFulfillmentDurationByRequestID(opts *bind.CallOpts, reqID *big.Int) (*big.Int, error)
-
- IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error)
-
- Owner(opts *bind.CallOpts) (common.Address, error)
-
- PendingRequests(opts *bind.CallOpts) ([]*big.Int, error)
-
- RequestHeights(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SReceivedRandomnessByRequestID(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SArguments(opts *bind.CallOpts) ([]byte, error)
-
- SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error)
-
- SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error)
-
- SFulfillmentDurationInBlocks(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SGasAvailable(opts *bind.CallOpts) (*big.Int, error)
-
- SMostRecentRequestID(opts *bind.CallOpts) (*big.Int, error)
-
- SMyBeaconRequests(opts *bind.CallOpts, arg0 *big.Int) (SMyBeaconRequests,
-
- error)
-
- SRandomWords(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- SRawFulfillmentDurationInBlocks(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SRequestIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SRequestOutputHeights(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SRequestsIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SResetCounter(opts *bind.CallOpts) (*big.Int, error)
-
- SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error)
-
- SSlowestRequestID(opts *bind.CallOpts) (*big.Int, error)
-
- SSubId(opts *bind.CallOpts) (uint64, error)
-
- STotalFulfilled(opts *bind.CallOpts) (*big.Int, error)
-
- STotalRequests(opts *bind.CallOpts) (*big.Int, error)
-
- AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
-
- RawFulfillRandomWords(opts *bind.TransactOpts, requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error)
-
- Reset(opts *bind.TransactOpts) (*types.Transaction, error)
-
- SetCoordinator(opts *bind.TransactOpts, coordinator common.Address) (*types.Transaction, error)
-
- SetFail(opts *bind.TransactOpts, shouldFail bool) (*types.Transaction, error)
-
- StoreBeaconRequest(opts *bind.TransactOpts, reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error)
-
- TestRedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int) (*types.Transaction, error)
-
- TestRequestRandomness(opts *bind.TransactOpts, numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error)
-
- TestRequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error)
-
- TestRequestRandomnessFulfillmentBatch(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confirmationDelayArg *big.Int, callbackGasLimit uint32, arguments []byte, batchSize *big.Int) (*types.Transaction, error)
-
- TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
-
- FilterCoordinatorUpdated(opts *bind.FilterOpts, coordinator []common.Address) (*LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator, error)
-
- WatchCoordinatorUpdated(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerCoordinatorUpdated, coordinator []common.Address) (event.Subscription, error)
-
- ParseCoordinatorUpdated(log types.Log) (*LoadTestBeaconVRFConsumerCoordinatorUpdated, error)
-
- FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator, error)
-
- WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferRequested(log types.Log) (*LoadTestBeaconVRFConsumerOwnershipTransferRequested, error)
-
- FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LoadTestBeaconVRFConsumerOwnershipTransferredIterator, error)
-
- WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferred(log types.Log) (*LoadTestBeaconVRFConsumerOwnershipTransferred, error)
-
- ParseLog(log types.Log) (generated.AbigenLog, error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/ocr2vrf/generated/vrf_beacon/vrf_beacon.go b/core/gethwrappers/ocr2vrf/generated/vrf_beacon/vrf_beacon.go
deleted file mode 100644
index b44019de548..00000000000
--- a/core/gethwrappers/ocr2vrf/generated/vrf_beacon/vrf_beacon.go
+++ /dev/null
@@ -1,2846 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package vrf_beacon
-
-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
-)
-
-type ECCArithmeticG1Point struct {
- P [2]*big.Int
-}
-
-type KeyDataStructKeyData struct {
- PublicKey []byte
- Hashes [][32]byte
-}
-
-type VRFBeaconReportReport struct {
- Outputs []VRFBeaconTypesVRFOutput
- JuelsPerFeeCoin *big.Int
- ReasonableGasPrice uint64
- RecentBlockHeight uint64
- RecentBlockHash [32]byte
-}
-
-type VRFBeaconTypesCallback struct {
- RequestID *big.Int
- NumWords uint16
- Requester common.Address
- Arguments []byte
- GasAllowance *big.Int
- SubID *big.Int
- GasPrice *big.Int
- WeiPerUnitLink *big.Int
-}
-
-type VRFBeaconTypesCostedCallback struct {
- Callback VRFBeaconTypesCallback
- Price *big.Int
-}
-
-type VRFBeaconTypesOutputServed struct {
- Height uint64
- ConfirmationDelay *big.Int
- ProofG1X *big.Int
- ProofG1Y *big.Int
-}
-
-type VRFBeaconTypesVRFOutput struct {
- BlockHeight uint64
- ConfirmationDelay *big.Int
- VrfOutput ECCArithmeticG1Point
- Callbacks []VRFBeaconTypesCostedCallback
- ShouldStore bool
-}
-
-var VRFBeaconMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"contractIVRFCoordinatorProducerAPI\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"contractDKG\",\"name\":\"keyProvider\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"keyID\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"CalldataLengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotAcceptPayeeship\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"providedHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"onchainHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"}],\"name\":\"HistoryDomainSeparatorWrong\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numTransmitters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numPayees\",\"type\":\"uint256\"}],\"name\":\"IncorrectNumberOfPayees\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expectedNumSignatures\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"actualBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredBalance\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyProvider\",\"type\":\"address\"}],\"name\":\"KeyInfoMustComeFromProvider\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeftGasExceedsInitialGas\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeOwnerOrBillingAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"numFaultyOracles\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"}],\"name\":\"NumberOfFaultyOraclesTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"expectedLength\",\"type\":\"uint256\"}],\"name\":\"OnchainConfigHasWrongLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCurrentPayee\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"existingPayee\",\"type\":\"address\"}],\"name\":\"PayeeAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"repeatedSignerAddress\",\"type\":\"address\"}],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"repeatedTransmitterAddress\",\"type\":\"address\"}],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportDoesNotContainNewOutputs\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numTransmitters\",\"type\":\"uint256\"}],\"name\":\"SignersTransmittersMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"maxOracles\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"providedOracles\",\"type\":\"uint256\"}],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ocrVersion\",\"type\":\"uint64\"}],\"name\":\"UnknownConfigVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractAccessControllerInterface\",\"name\":\"old\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractAccessControllerInterface\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"BillingAccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maximumGasPrice\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"observationPayment\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"transmissionPayment\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"accountingGas\",\"type\":\"uint24\"}],\"name\":\"BillingSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"NewTransmission\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"contractLinkTokenInterface\",\"name\":\"linkToken\",\"type\":\"address\"}],\"name\":\"OraclePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"recentBlockHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint256\",\"name\":\"proofG1X\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofG1Y\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structVRFBeaconTypes.OutputServed[]\",\"name\":\"outputsServed\",\"type\":\"tuple[]\"}],\"name\":\"OutputsServed\",\"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\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previous\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"requestIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"successfulFulfillment\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"truncatedErrorData\",\"type\":\"bytes[]\"},{\"indexed\":false,\"internalType\":\"uint96[]\",\"name\":\"subBalances\",\"type\":\"uint96[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"subIDs\",\"type\":\"uint256[]\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nextBeaconOutputHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAllowance\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weiPerUnitLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"costJuels\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSubBalance\",\"type\":\"uint256\"}],\"name\":\"RandomnessFulfillmentRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"}],\"name\":\"RandomnessRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nextBeaconOutputHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"costJuels\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSubBalance\",\"type\":\"uint256\"}],\"name\":\"RandomnessRequested\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"NUM_CONF_DELAYS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"p\",\"type\":\"uint256[2]\"}],\"internalType\":\"structECCArithmetic.G1Point\",\"name\":\"vrfOutput\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"gasAllowance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weiPerUnitLink\",\"type\":\"uint256\"}],\"internalType\":\"structVRFBeaconTypes.Callback\",\"name\":\"callback\",\"type\":\"tuple\"},{\"internalType\":\"uint96\",\"name\":\"price\",\"type\":\"uint96\"}],\"internalType\":\"structVRFBeaconTypes.CostedCallback[]\",\"name\":\"callbacks\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"shouldStore\",\"type\":\"bool\"}],\"internalType\":\"structVRFBeaconTypes.VRFOutput[]\",\"name\":\"outputs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"recentBlockHeight\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"recentBlockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structVRFBeaconReport.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"exposeType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBilling\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"maximumGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"observationPayment\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"transmissionPayment\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"accountingGas\",\"type\":\"uint24\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBillingAccessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_coordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorProducerAPI\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_link\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"structKeyDataStruct.KeyData\",\"name\":\"kd\",\"type\":\"tuple\"}],\"name\":\"keyGenerated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"availableBalance\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"newKeyRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitterAddress\",\"type\":\"address\"}],\"name\":\"owedPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_keyID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_keyProvider\",\"outputs\":[{\"internalType\":\"contractDKG\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_provingKeyHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"maximumGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"observationPayment\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"transmissionPayment\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"accountingGas\",\"type\":\"uint24\"}],\"name\":\"setBilling\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"_billingAccessController\",\"type\":\"address\"}],\"name\":\"setBillingAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60e06040523480156200001157600080fd5b5060405162004dfe38038062004dfe8339810160408190526200003491620001c7565b8181858581813380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000103565b5050506001600160a01b03918216608052811660a052600e80546001600160a01b03191695909116949094179093555060c05250620002219350505050565b336001600160a01b038216036200015d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620001c457600080fd5b50565b60008060008060808587031215620001de57600080fd5b8451620001eb81620001ae565b6020860151909450620001fe81620001ae565b60408601519093506200021181620001ae565b6060959095015193969295505050565b60805160a05160c051614b28620002d660003960006104810152600081816103820152818161114e015281816112260152818161131c0152818161141d015281816114bb01528181612216015281816122ee015281816124650152818161275a01528181612b8301528181612c5b0152818161316501526136cd01526000818161032b015281816112540152818161144a0152818161231c015281816124c301528181612c8901526130500152614b286000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c8063afcb95d7116100f9578063d09dc33911610097578063e53bbc9a11610071578063e53bbc9a146104c7578063eb5dcd6c146104da578063f2fde38b146104ed578063fbffd2c11461050057600080fd5b8063d09dc339146104a3578063d57fc45a146104ab578063e3d0e712146104b457600080fd5b8063bf2732c7116100d3578063bf2732c714610438578063c10753291461044b578063c4c92b371461045e578063cc31f7dd1461047c57600080fd5b8063afcb95d7146103e8578063b121e14714610412578063b1dc65a41461042557600080fd5b806379ba5097116101665780638a1b1772116101405780638a1b17721461037d5780638ac28d5a146103a45780638da5cb5b146103b75780639c849b30146103d557600080fd5b806379ba50971461031e5780637d253aff1461032657806381ff70481461034d57600080fd5b806329937268116101a257806329937268146102415780632f7527cc146102b757806355e48749146102d15780635f27026f146102d957600080fd5b806305aeed58146101c95780630eafb25b146101dc578063181f5a7714610202575b600080fd5b6101da6101d73660046137f7565b50565b005b6101ef6101ea366004613854565b610513565b6040519081526020015b60405180910390f35b604080518082018252600f81527f565246426561636f6e20312e302e300000000000000000000000000000000000602082015290516101f991906138df565b60025460035460408051610100840467ffffffffffffffff9081168252690100000000000000000085048116602083015271010000000000000000000000000000000000909404841691810191909152918116606083015268010000000000000000900462ffffff16608082015260a0016101f9565b6102bf600881565b60405160ff90911681526020016101f9565b6101da61059f565b600e546102f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f9565b6101da61061c565b6102f97f000000000000000000000000000000000000000000000000000000000000000081565b6004546005546040805163ffffffff808516825264010000000090940490931660208401528201526060016101f9565b6102f97f000000000000000000000000000000000000000000000000000000000000000081565b6101da6103b2366004613854565b610719565b60005473ffffffffffffffffffffffffffffffffffffffff166102f9565b6101da6103e336600461393e565b610782565b6005546006546040805160008152602081019390935263ffffffff909116908201526060016101f9565b6101da610420366004613854565b6109d4565b6101da6104333660046139ec565b610acc565b6101da610446366004613c89565b610f87565b6101da610459366004613d56565b611046565b600d5473ffffffffffffffffffffffffffffffffffffffff166102f9565b6101ef7f000000000000000000000000000000000000000000000000000000000000000081565b6101ef6113e0565b6101ef600f5481565b6101da6104c2366004613db9565b611573565b6101da6104d5366004613eb8565b611dc9565b6101da6104e8366004613f29565b61201b565b6101da6104fb366004613854565b612174565b6101da61050e366004613854565b612185565b73ffffffffffffffffffffffffffffffffffffffff811660009081526007602090815260408083208151606081018352905460ff80821615158084526101008304909116948301949094526201000090046bffffffffffffffffffffffff1691810191909152906105875750600092915050565b604001516bffffffffffffffffffffffff1692915050565b600e5473ffffffffffffffffffffffffffffffffffffffff16338114610614576040517f292f4fb500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b506000600f55565b60015473ffffffffffffffffffffffffffffffffffffffff16331461069d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161060b565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600b6020526040902054163314610779576040517fdce38c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101d781612196565b61078a612569565b8281146107cd576040517f36d20459000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161060b565b60005b838110156109cd5760008585838181106107ec576107ec613f62565b90506020020160208101906108019190613854565b9050600084848481811061081757610817613f62565b905060200201602081019061082c9190613854565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600b602052604090205491925016801580158161089257508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156108e9576040517febdf175600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301528316602482015260440161060b565b73ffffffffffffffffffffffffffffffffffffffff8481166000908152600b6020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016858316908117909155908316146109b6578273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b360405160405180910390a45b5050505080806109c590613fc0565b9150506107d0565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600c6020526040902054163314610a34576040517f9d12ec4f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600b602090815260408083208054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217909355600c909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b60005a6040805160c08101825260025460ff808216835267ffffffffffffffff61010083048116602080860191909152690100000000000000000084048216858701527101000000000000000000000000000000000090930481166060850152600354908116608085015262ffffff680100000000000000009091041660a08401523360009081526007835293909320549394509092908c01359116610ba0576040517fb1c1f68e00000000000000000000000000000000000000000000000000000000815233600482015260240161060b565b6005548b3514610bea576005546040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091528b35602482015260440161060b565b610bf88a8a8a8a8a8a6125ec565b8151610c05906001613ff8565b60ff1687141580610c165750868514155b15610c6e578151610c28906001613ff8565b6040517ffc33647500000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018890526044810186905260640161060b565b60008a8a604051610c80929190614011565b604051908190038120610c97918e90602001614021565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012083830190925260008084529083018190529092509060005b8a811015610e885760006001858a8460208110610d0457610d04613f62565b610d1191901a601b613ff8565b8f8f86818110610d2357610d23613f62565b905060200201358e8e87818110610d3c57610d3c613f62565b9050602002013560405160008152602001604052604051610d79949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610d9b573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526008602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955092509050610e61576040517f20fb74ee00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161060b565b826020015160080260ff166001901b84019350508080610e8090613fc0565b915050610ce5565b5081827e010101010101010101010101010101010101010101010101010101010101011614610ee3576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060009150819050610f328d826020020135848e8e8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061267c92505050565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff600888901c161790559092509050610f7884838388336128c6565b50505050505050505050505050565b600e5473ffffffffffffffffffffffffffffffffffffffff16338114610ff7576040517f292f4fb500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161060b565b81516040516110099190602001614035565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120600f555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906111075750600d546040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690636b14daf8906110c4903390600090369060040161409a565b602060405180830381865afa1580156110e1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110591906140da565b155b1561113e576040517fc04ecc2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611148612a24565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663597d2f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111db91906140f5565b905060006111e9828461410e565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561129b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bf91906140f5565b905081811015611305576040517fcf479181000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161060b565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f99b1d688761135561134f8686614121565b89612b1f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401600060405180830381600087803b1580156113c057600080fd5b505af11580156113d4573d6000803e3d6000fd5b50505050505050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015260009182917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611491573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b591906140f5565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663597d2f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611524573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154891906140f5565b90506000611554612a24565b9050816115618285614134565b61156b9190614134565b935050505090565b888787601f8311156115bb576040517f809fc428000000000000000000000000000000000000000000000000000000008152601f60048201526024810184905260440161060b565b8183146115fe576040517f988a0804000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260440161060b565b61160981600361415b565b60ff168311611650576040517ffda9db7800000000000000000000000000000000000000000000000000000000815260ff821660048201526024810184905260440161060b565b61165c8160ff16612b39565b611664612569565b60006040518060c001604052808f8f80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018d8d8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060ff8c1660208083019190915260408051601f8d0183900483028101830182528c8152920191908c908c908190840183828082843760009201919091525050509082525067ffffffffffffffff891660208083019190915260408051601f8a01839004830281018301825289815292019190899089908190840183828082843760009201919091525050509152509050611786612b73565b60095460005b8181101561187f576000600982815481106117a9576117a9613f62565b6000918252602082200154600a805473ffffffffffffffffffffffffffffffffffffffff909216935090849081106117e3576117e3613f62565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff948516835260088252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905594168252600790529190912080547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169055508061187781613fc0565b91505061178c565b5061188c6009600061373a565b611898600a600061373a565b60005b825151811015611c215760086000846000015183815181106118bf576118bf613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff161561196357825180518290811061190c5761190c613f62565b60200260200101516040517f7451f83e00000000000000000000000000000000000000000000000000000000815260040161060b919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b604080518082019091526001815260ff82166020820152835180516008916000918590811061199457611994613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281810192909252604001600090812083518154948401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff161761010060ff90951694909402939093179092558401518051600792919084908110611a4657611a46613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611aec5782602001518181518110611a9557611a95613f62565b60200260200101516040517fe8d2989900000000000000000000000000000000000000000000000000000000815260040161060b919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180606001604052806001151581526020018260ff16815260200160006bffffffffffffffffffffffff168152506007600085602001518481518110611b3657611b36613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600020835181549385015194909201516bffffffffffffffffffffffff1662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff931515939093167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090941693909317919091179290921617905580611c1981613fc0565b91505061189b565b5081518051611c3891600991602090910190613758565b506020808301518051611c4f92600a920190613758565b506040820151600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600454640100000000900463ffffffff16611c9f6131d5565b6004805463ffffffff928316640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff82168117909255600092611ced9281169116176001614177565b905080600460006101000a81548163ffffffff021916908363ffffffff1602179055506000611d4146308463ffffffff16886000015189602001518a604001518b606001518c608001518d60a0015161326c565b9050806005819055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e058360055484886000015189602001518a604001518b606001518c608001518d60a00151604051611da3999897969594939291906141e5565b60405180910390a1611db58d8d613317565b505050505050505050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611e8a5750600d546040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690636b14daf890611e47903390600090369060040161409a565b602060405180830381865afa158015611e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8891906140da565b155b15611ec1576040517fc04ecc2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ec9612b73565b6002805467ffffffffffffffff8581167101000000000000000000000000000000000081027fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff898416690100000000000000000081027fffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffff8d87166101008102919091167fffffffffffffffffffffffffffffff00000000000000000000000000000000ff909816979097171791909116919091179094556003805462ffffff87166801000000000000000081027fffffffffffffffffffffffffffffffffffffffffff00000000000000000000009092169489169485179190911790915560408051948552602085019590955293830152606082015260808101919091527f49275ddcdfc9c0519b3d094308c8bf675f06070a754ce90c152163cb6e66e8a09060a00160405180910390a15050505050565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600b602052604090205416331461207b576040517fdce38c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811633036120ca576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600c6020526040902080548383167fffffffffffffffffffffffff00000000000000000000000000000000000000008216811790925590911690811461216f5760405173ffffffffffffffffffffffffffffffffffffffff8084169133918616907f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836790600090a45b505050565b61217c612569565b6101d781613325565b61218d612569565b6101d78161341a565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600760209081526040918290208251606081018452905460ff80821615158084526101008304909116938301939093526201000090046bffffffffffffffffffffffff1692810192909252612205575050565b600061221083610513565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663597d2f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561227f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a391906140f5565b905060006122b1828461410e565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612363573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238791906140f5565b9050818110156123cd576040517fcf479181000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161060b565b83156125615773ffffffffffffffffffffffffffffffffffffffff8681166000908152600b602090815260408083205460079092529182902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905590517ff99b1d680000000000000000000000000000000000000000000000000000000081529082166004820181905260248201879052917f0000000000000000000000000000000000000000000000000000000000000000169063f99b1d6890604401600060405180830381600087803b1580156124a957600080fd5b505af11580156124bd573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c8860405161255791815260200190565b60405180910390a4505b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146125ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161060b565b565b60006125f982602061427b565b61260485602061427b565b6126108861014461410e565b61261a919061410e565b612624919061410e565b61262f90600061410e565b9050368114612673576040517ff7b94f0a0000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161060b565b50505050505050565b60008060008380602001905181019061269591906144bf565b905060006126a682606001516134c2565b90508082608001511461270957608082015160608301516040517faed0afe500000000000000000000000000000000000000000000000000000000815260048101929092526024820183905267ffffffffffffffff16604482015260640161060b565b81516020830151604080850151606086015191517f76f2e3f400000000000000000000000000000000000000000000000000000000815260009473ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016946376f2e3f4946127929492939192916004016147fa565b6020604051808303816000875af11580156127b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d591906140da565b90508061280e576040517f69c920fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8664ffffffffff167ffc3c7a7927e878a0fca37c904953c3c75cee3ca1d1640184a0ab1c65eec6274333856020015186604001518c6040516128a5949392919073ffffffffffffffffffffffffffffffffffffffff94909416845277ffffffffffffffffffffffffffffffffffffffffffffffff92909216602084015267ffffffffffffffff166040830152606082015260800190565b60405180910390a28260200151836040015194509450505050935093915050565b60006128f23a67ffffffffffffffff8616156128e257856128e8565b87604001515b88602001516135a5565b90506010360260005a9050600061291b8663ffffffff1685858c60a0015162ffffff16866135f6565b90506000670de0b6b3a764000077ffffffffffffffffffffffffffffffffffffffffffffffff8a16830273ffffffffffffffffffffffffffffffffffffffff881660009081526007602052604090205460808d01519290910492506201000090046bffffffffffffffffffffffff9081169167ffffffffffffffff16828401019081168211156129b157505050505050506109cd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260076020526040902080546bffffffffffffffffffffffff90921662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff9092169190911790555050505050505050505050565b600080600a805480602002602001604051908101604052809291908181526020018280548015612a8a57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612a5f575b505083519394506000925050505b81811015612b195760076000848381518110612ab657612ab6613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054612b05906201000090046bffffffffffffffffffffffff168561410e565b935080612b1181613fc0565b915050612a98565b50505090565b600081831015612b30575081612b33565b50805b92915050565b806000036101d7576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b7d612a24565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663597d2f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1091906140f5565b90506000612c1e828461410e565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612cd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cf491906140f5565b905081811015612d3a576040517fcf479181000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161060b565b6000600a805480602002602001604051908101604052809291908181526020018280548015612d9f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612d74575b5050505050905060008151905060008167ffffffffffffffff811115612dc757612dc7613aa3565b604051908082528060200260200182016040528015612df0578160200160208202803683370190505b50905060008267ffffffffffffffff811115612e0e57612e0e613aa3565b604051908082528060200260200182016040528015612e37578160200160208202803683370190505b5090506000805b8481101561311157600060076000888481518110612e5e57612e5e613f62565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160029054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060076000898581518110612ee457612ee4613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080546bffffffffffffffffffffffff9290921662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff909216919091179055808015613107576000600b60008a8681518110612f7557612f75613f62565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080878681518110612fed57612fed613f62565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508186868151811061303a5761303a613f62565b60200260200101818152505084806001019550507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168a86815181106130ae576130ae613f62565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c856040516130fd91815260200190565b60405180910390a4505b5050600101612e3e565b5081518114613121578082528083525b8151156131ca576040517f73433a2f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906373433a2f9061319c908690869060040161496a565b600060405180830381600087803b1580156131b657600080fd5b505af1158015610f78573d6000803e3d6000fd5b505050505050505050565b60004661a4b18114806131ea575062066eed81145b1561326557606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561323b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061325f91906140f5565b91505090565b4391505090565b6000808a8a8a8a8a8a8a8a8a604051602001613290999897969594939291906149c1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b613321828261363e565b5050565b3373ffffffffffffffffffffffffffffffffffffffff8216036133a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161060b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600d5473ffffffffffffffffffffffffffffffffffffffff908116908216811461332157600d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84811691821790925560408051928416835260208301919091527f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d48912910160405180910390a15050565b60004661a4b18114806134d7575062066eed81145b15613595576101008367ffffffffffffffff166134f26131d5565b6134fc9190614121565b111561350b5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a8290602401602060405180830381865afa15801561356a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358e91906140f5565b9392505050565b505067ffffffffffffffff164090565b60008367ffffffffffffffff84168110156135d9576002858567ffffffffffffffff1603816135d6576135d661493b565b04015b6135ed818467ffffffffffffffff16612b1f565b95945050505050565b600081861015613632576040517f3fef97df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50909303019091010290565b610100818114613680578282826040517f418a179b00000000000000000000000000000000000000000000000000000000815260040161060b93929190614a56565b600061368e83850185614a7a565b90506040517f8eef585f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690638eef585f90613702908490600401614ae4565b600060405180830381600087803b15801561371c57600080fd5b505af1158015613730573d6000803e3d6000fd5b5050505050505050565b50805460008255906000526020600020908101906101d791906137e2565b8280548282559060005260206000209081019282156137d2579160200282015b828111156137d257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613778565b506137de9291506137e2565b5090565b5b808211156137de57600081556001016137e3565b60006020828403121561380957600080fd5b813567ffffffffffffffff81111561382057600080fd5b820160a0818503121561358e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff811681146101d757600080fd5b60006020828403121561386657600080fd5b813561358e81613832565b60005b8381101561388c578181015183820152602001613874565b50506000910152565b600081518084526138ad816020860160208601613871565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061358e6020830184613895565b60008083601f84011261390457600080fd5b50813567ffffffffffffffff81111561391c57600080fd5b6020830191508360208260051b850101111561393757600080fd5b9250929050565b6000806000806040858703121561395457600080fd5b843567ffffffffffffffff8082111561396c57600080fd5b613978888389016138f2565b9096509450602087013591508082111561399157600080fd5b5061399e878288016138f2565b95989497509550505050565b60008083601f8401126139bc57600080fd5b50813567ffffffffffffffff8111156139d457600080fd5b60208301915083602082850101111561393757600080fd5b60008060008060008060008060e0898b031215613a0857600080fd5b606089018a811115613a1957600080fd5b8998503567ffffffffffffffff80821115613a3357600080fd5b613a3f8c838d016139aa565b909950975060808b0135915080821115613a5857600080fd5b613a648c838d016138f2565b909750955060a08b0135915080821115613a7d57600080fd5b50613a8a8b828c016138f2565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613af557613af5613aa3565b60405290565b604051610100810167ffffffffffffffff81118282101715613af557613af5613aa3565b60405160a0810167ffffffffffffffff81118282101715613af557613af5613aa3565b6040516020810167ffffffffffffffff81118282101715613af557613af5613aa3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bac57613bac613aa3565b604052919050565b600067ffffffffffffffff821115613bce57613bce613aa3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600067ffffffffffffffff821115613c1457613c14613aa3565b5060051b60200190565b600082601f830112613c2f57600080fd5b81356020613c44613c3f83613bfa565b613b65565b82815260059290921b84018101918181019086841115613c6357600080fd5b8286015b84811015613c7e5780358352918301918301613c67565b509695505050505050565b60006020808385031215613c9c57600080fd5b823567ffffffffffffffff80821115613cb457600080fd5b9084019060408287031215613cc857600080fd5b613cd0613ad2565b823582811115613cdf57600080fd5b8301601f81018813613cf057600080fd5b8035613cfe613c3f82613bb4565b8181528987838501011115613d1257600080fd5b818784018883013760008783830101528084525050508383013582811115613d3957600080fd5b613d4588828601613c1e565b948201949094529695505050505050565b60008060408385031215613d6957600080fd5b8235613d7481613832565b946020939093013593505050565b803560ff81168114613d9357600080fd5b919050565b67ffffffffffffffff811681146101d757600080fd5b8035613d9381613d98565b60008060008060008060008060008060c08b8d031215613dd857600080fd5b8a3567ffffffffffffffff80821115613df057600080fd5b613dfc8e838f016138f2565b909c509a5060208d0135915080821115613e1557600080fd5b613e218e838f016138f2565b909a509850889150613e3560408e01613d82565b975060608d0135915080821115613e4b57600080fd5b613e578e838f016139aa565b9097509550859150613e6b60808e01613dae565b945060a08d0135915080821115613e8157600080fd5b50613e8e8d828e016139aa565b915080935050809150509295989b9194979a5092959850565b62ffffff811681146101d757600080fd5b600080600080600060a08688031215613ed057600080fd5b8535613edb81613d98565b94506020860135613eeb81613d98565b93506040860135613efb81613d98565b92506060860135613f0b81613d98565b91506080860135613f1b81613ea7565b809150509295509295909350565b60008060408385031215613f3c57600080fd5b8235613f4781613832565b91506020830135613f5781613832565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613ff157613ff1613f91565b5060010190565b60ff8181168382160190811115612b3357612b33613f91565b8183823760009101908152919050565b828152606082602083013760800192915050565b60008251614047818460208701613871565b9190910192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006135ed604083018486614051565b80518015158114613d9357600080fd5b6000602082840312156140ec57600080fd5b61358e826140ca565b60006020828403121561410757600080fd5b5051919050565b80820180821115612b3357612b33613f91565b81810381811115612b3357612b33613f91565b818103600083128015838313168383128216171561415457614154613f91565b5092915050565b60ff818116838216029081169081811461415457614154613f91565b63ffffffff81811683821601908082111561415457614154613f91565b600081518084526020808501945080840160005b838110156141da57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016141a8565b509495945050505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526142158184018a614194565b905082810360808401526142298189614194565b905060ff871660a084015282810360c08401526142468187613895565b905067ffffffffffffffff851660e084015282810361010084015261426b8185613895565b9c9b505050505050505050505050565b8082028115828204841417612b3357612b33613f91565b8051613d9381613d98565b805161ffff81168114613d9357600080fd5b8051613d9381613832565b600082601f8301126142cb57600080fd5b81516142d9613c3f82613bb4565b8181528460208386010111156142ee57600080fd5b6142ff826020830160208701613871565b949350505050565b80516bffffffffffffffffffffffff81168114613d9357600080fd5b600082601f83011261433457600080fd5b81516020614344613c3f83613bfa565b82815260059290921b8401810191818101908684111561436357600080fd5b8286015b84811015613c7e57805167ffffffffffffffff8082111561438757600080fd5b908801907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06040838c03820112156143be57600080fd5b6143c6613ad2565b87840151838111156143d757600080fd5b8401610100818e03840112156143ec57600080fd5b6143f4613afb565b92508881015183526144086040820161429d565b89840152614418606082016142af565b604084015260808101518481111561442f57600080fd5b61443d8e8b838501016142ba565b60608501525061444f60a08201614307565b608084015260c081015160a084015260e081015160c084015261010081015160e08401525081815261448360408501614307565b818901528652505050918301918301614367565b805177ffffffffffffffffffffffffffffffffffffffffffffffff81168114613d9357600080fd5b6000602082840312156144d157600080fd5b815167ffffffffffffffff808211156144e957600080fd5b9083019060a082860312156144fd57600080fd5b614505613b1f565b82518281111561451457600080fd5b8301601f8101871361452557600080fd5b8051614533613c3f82613bfa565b8082825260208201915060208360051b85010192508983111561455557600080fd5b602084015b838110156146a25780518781111561457157600080fd5b850160c0818d037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00112156145a557600080fd5b6145ad613b1f565b60208201516145bb81613d98565b815260408201516145cb81613ea7565b60208201526040828e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa001121561460257600080fd5b61460a613b42565b8d607f84011261461957600080fd5b614621613ad2565b808f60a08601111561463257600080fd5b606085015b60a08601811015614652578051835260209283019201614637565b50825250604082015260a08201518981111561466d57600080fd5b61467c8e602083860101614323565b60608301525061468e60c083016140ca565b60808201528452506020928301920161455a565b508452506146b591505060208401614497565b60208201526146c660408401614292565b60408201526146d760608401614292565b60608201526080830151608082015280935050505092915050565b600081518084526020808501808196508360051b8101915082860160005b858110156147ed57828403895281516040815181875280518288015287810151606061ffff8216818a01528383015193506080915073ffffffffffffffffffffffffffffffffffffffff8416828a01528083015193505061010060a081818b015261477f6101408b0186613895565b9284015192945060c06147a18b8201856bffffffffffffffffffffffff169052565b9084015160e08b81019190915290840151918a01919091529091015161012088015250908601516bffffffffffffffffffffffff16948601949094529784019790840190600101614710565b5091979650505050505050565b6000608080830181845280885180835260a092508286019150828160051b8701016020808c016000805b858110156148df578a85037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600187528251805167ffffffffffffffff1686528481015162ffffff16858701526040808201515160c091859089015b600282101561489e57825181529188019160019190910190880161487f565b5050506060820151818c8901526148b7828901826146f2565b928c0151801515898d01529291506148cc9050565b9785019795505091830191600101614824565b50505081965061490a8189018c77ffffffffffffffffffffffffffffffffffffffffffffffff169052565b505050505050614926604083018567ffffffffffffffff169052565b67ffffffffffffffff831660608301526135ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60408152600061497d6040830185614194565b82810360208481019190915284518083528582019282019060005b818110156149b457845183529383019391830191600101614998565b5090979650505050505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614a088285018b614194565b91508382036080850152614a1c828a614194565b915060ff881660a085015283820360c0850152614a398288613895565b90861660e0850152838103610100850152905061426b8185613895565b604081526000614a6a604083018587614051565b9050826020830152949350505050565b6000610100808385031215614a8e57600080fd5b83601f840112614a9d57600080fd5b614aa5613afb565b908301908085831115614ab757600080fd5b845b83811015614ada578035614acc81613ea7565b835260209283019201614ab9565b5095945050505050565b6101008101818360005b6008811015614b1257815162ffffff16835260209283019290910190600101614aee565b5050509291505056fea164736f6c6343000813000a",
-}
-
-var VRFBeaconABI = VRFBeaconMetaData.ABI
-
-var VRFBeaconBin = VRFBeaconMetaData.Bin
-
-func DeployVRFBeacon(auth *bind.TransactOpts, backend bind.ContractBackend, link common.Address, coordinator common.Address, keyProvider common.Address, keyID [32]byte) (common.Address, *types.Transaction, *VRFBeacon, error) {
- parsed, err := VRFBeaconMetaData.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(VRFBeaconBin), backend, link, coordinator, keyProvider, keyID)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &VRFBeacon{VRFBeaconCaller: VRFBeaconCaller{contract: contract}, VRFBeaconTransactor: VRFBeaconTransactor{contract: contract}, VRFBeaconFilterer: VRFBeaconFilterer{contract: contract}}, nil
-}
-
-type VRFBeacon struct {
- address common.Address
- abi abi.ABI
- VRFBeaconCaller
- VRFBeaconTransactor
- VRFBeaconFilterer
-}
-
-type VRFBeaconCaller struct {
- contract *bind.BoundContract
-}
-
-type VRFBeaconTransactor struct {
- contract *bind.BoundContract
-}
-
-type VRFBeaconFilterer struct {
- contract *bind.BoundContract
-}
-
-type VRFBeaconSession struct {
- Contract *VRFBeacon
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type VRFBeaconCallerSession struct {
- Contract *VRFBeaconCaller
- CallOpts bind.CallOpts
-}
-
-type VRFBeaconTransactorSession struct {
- Contract *VRFBeaconTransactor
- TransactOpts bind.TransactOpts
-}
-
-type VRFBeaconRaw struct {
- Contract *VRFBeacon
-}
-
-type VRFBeaconCallerRaw struct {
- Contract *VRFBeaconCaller
-}
-
-type VRFBeaconTransactorRaw struct {
- Contract *VRFBeaconTransactor
-}
-
-func NewVRFBeacon(address common.Address, backend bind.ContractBackend) (*VRFBeacon, error) {
- abi, err := abi.JSON(strings.NewReader(VRFBeaconABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindVRFBeacon(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &VRFBeacon{address: address, abi: abi, VRFBeaconCaller: VRFBeaconCaller{contract: contract}, VRFBeaconTransactor: VRFBeaconTransactor{contract: contract}, VRFBeaconFilterer: VRFBeaconFilterer{contract: contract}}, nil
-}
-
-func NewVRFBeaconCaller(address common.Address, caller bind.ContractCaller) (*VRFBeaconCaller, error) {
- contract, err := bindVRFBeacon(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconCaller{contract: contract}, nil
-}
-
-func NewVRFBeaconTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFBeaconTransactor, error) {
- contract, err := bindVRFBeacon(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconTransactor{contract: contract}, nil
-}
-
-func NewVRFBeaconFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFBeaconFilterer, error) {
- contract, err := bindVRFBeacon(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconFilterer{contract: contract}, nil
-}
-
-func bindVRFBeacon(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := VRFBeaconMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_VRFBeacon *VRFBeaconRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _VRFBeacon.Contract.VRFBeaconCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_VRFBeacon *VRFBeaconRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VRFBeacon.Contract.VRFBeaconTransactor.contract.Transfer(opts)
-}
-
-func (_VRFBeacon *VRFBeaconRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _VRFBeacon.Contract.VRFBeaconTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_VRFBeacon *VRFBeaconCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _VRFBeacon.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VRFBeacon.Contract.contract.Transfer(opts)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _VRFBeacon.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) NUMCONFDELAYS(opts *bind.CallOpts) (uint8, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "NUM_CONF_DELAYS")
-
- if err != nil {
- return *new(uint8), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) NUMCONFDELAYS() (uint8, error) {
- return _VRFBeacon.Contract.NUMCONFDELAYS(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) NUMCONFDELAYS() (uint8, error) {
- return _VRFBeacon.Contract.NUMCONFDELAYS(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) GetBilling(opts *bind.CallOpts) (GetBilling,
-
- error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "getBilling")
-
- outstruct := new(GetBilling)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.MaximumGasPrice = *abi.ConvertType(out[0], new(uint64)).(*uint64)
- outstruct.ReasonableGasPrice = *abi.ConvertType(out[1], new(uint64)).(*uint64)
- outstruct.ObservationPayment = *abi.ConvertType(out[2], new(uint64)).(*uint64)
- outstruct.TransmissionPayment = *abi.ConvertType(out[3], new(uint64)).(*uint64)
- outstruct.AccountingGas = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
-
- return *outstruct, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) GetBilling() (GetBilling,
-
- error) {
- return _VRFBeacon.Contract.GetBilling(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) GetBilling() (GetBilling,
-
- error) {
- return _VRFBeacon.Contract.GetBilling(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) GetBillingAccessController(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "getBillingAccessController")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) GetBillingAccessController() (common.Address, error) {
- return _VRFBeacon.Contract.GetBillingAccessController(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) GetBillingAccessController() (common.Address, error) {
- return _VRFBeacon.Contract.GetBillingAccessController(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) ICoordinator(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "i_coordinator")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) ICoordinator() (common.Address, error) {
- return _VRFBeacon.Contract.ICoordinator(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) ICoordinator() (common.Address, error) {
- return _VRFBeacon.Contract.ICoordinator(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) ILink(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "i_link")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) ILink() (common.Address, error) {
- return _VRFBeacon.Contract.ILink(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) ILink() (common.Address, error) {
- return _VRFBeacon.Contract.ILink(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails,
-
- error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "latestConfigDetails")
-
- outstruct := new(LatestConfigDetails)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32)
- outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32)
- outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte)
-
- return *outstruct, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) LatestConfigDetails() (LatestConfigDetails,
-
- error) {
- return _VRFBeacon.Contract.LatestConfigDetails(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) LatestConfigDetails() (LatestConfigDetails,
-
- error) {
- return _VRFBeacon.Contract.LatestConfigDetails(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch,
-
- error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "latestConfigDigestAndEpoch")
-
- outstruct := new(LatestConfigDigestAndEpoch)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool)
- outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte)
- outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32)
-
- return *outstruct, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch,
-
- error) {
- return _VRFBeacon.Contract.LatestConfigDigestAndEpoch(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch,
-
- error) {
- return _VRFBeacon.Contract.LatestConfigDigestAndEpoch(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "linkAvailableForPayment")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) LinkAvailableForPayment() (*big.Int, error) {
- return _VRFBeacon.Contract.LinkAvailableForPayment(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) LinkAvailableForPayment() (*big.Int, error) {
- return _VRFBeacon.Contract.LinkAvailableForPayment(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) OwedPayment(opts *bind.CallOpts, transmitterAddress common.Address) (*big.Int, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "owedPayment", transmitterAddress)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) OwedPayment(transmitterAddress common.Address) (*big.Int, error) {
- return _VRFBeacon.Contract.OwedPayment(&_VRFBeacon.CallOpts, transmitterAddress)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) OwedPayment(transmitterAddress common.Address) (*big.Int, error) {
- return _VRFBeacon.Contract.OwedPayment(&_VRFBeacon.CallOpts, transmitterAddress)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VRFBeacon.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 (_VRFBeacon *VRFBeaconSession) Owner() (common.Address, error) {
- return _VRFBeacon.Contract.Owner(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) Owner() (common.Address, error) {
- return _VRFBeacon.Contract.Owner(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) SKeyID(opts *bind.CallOpts) ([32]byte, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "s_keyID")
-
- if err != nil {
- return *new([32]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) SKeyID() ([32]byte, error) {
- return _VRFBeacon.Contract.SKeyID(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) SKeyID() ([32]byte, error) {
- return _VRFBeacon.Contract.SKeyID(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) SKeyProvider(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "s_keyProvider")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) SKeyProvider() (common.Address, error) {
- return _VRFBeacon.Contract.SKeyProvider(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) SKeyProvider() (common.Address, error) {
- return _VRFBeacon.Contract.SKeyProvider(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) SProvingKeyHash(opts *bind.CallOpts) ([32]byte, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "s_provingKeyHash")
-
- if err != nil {
- return *new([32]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) SProvingKeyHash() ([32]byte, error) {
- return _VRFBeacon.Contract.SProvingKeyHash(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) SProvingKeyHash() ([32]byte, error) {
- return _VRFBeacon.Contract.SProvingKeyHash(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) {
- var out []interface{}
- err := _VRFBeacon.contract.Call(opts, &out, "typeAndVersion")
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_VRFBeacon *VRFBeaconSession) TypeAndVersion() (string, error) {
- return _VRFBeacon.Contract.TypeAndVersion(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconCallerSession) TypeAndVersion() (string, error) {
- return _VRFBeacon.Contract.TypeAndVersion(&_VRFBeacon.CallOpts)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "acceptOwnership")
-}
-
-func (_VRFBeacon *VRFBeaconSession) AcceptOwnership() (*types.Transaction, error) {
- return _VRFBeacon.Contract.AcceptOwnership(&_VRFBeacon.TransactOpts)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) AcceptOwnership() (*types.Transaction, error) {
- return _VRFBeacon.Contract.AcceptOwnership(&_VRFBeacon.TransactOpts)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) AcceptPayeeship(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "acceptPayeeship", transmitter)
-}
-
-func (_VRFBeacon *VRFBeaconSession) AcceptPayeeship(transmitter common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.AcceptPayeeship(&_VRFBeacon.TransactOpts, transmitter)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) AcceptPayeeship(transmitter common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.AcceptPayeeship(&_VRFBeacon.TransactOpts, transmitter)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) ExposeType(opts *bind.TransactOpts, arg0 VRFBeaconReportReport) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "exposeType", arg0)
-}
-
-func (_VRFBeacon *VRFBeaconSession) ExposeType(arg0 VRFBeaconReportReport) (*types.Transaction, error) {
- return _VRFBeacon.Contract.ExposeType(&_VRFBeacon.TransactOpts, arg0)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) ExposeType(arg0 VRFBeaconReportReport) (*types.Transaction, error) {
- return _VRFBeacon.Contract.ExposeType(&_VRFBeacon.TransactOpts, arg0)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) KeyGenerated(opts *bind.TransactOpts, kd KeyDataStructKeyData) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "keyGenerated", kd)
-}
-
-func (_VRFBeacon *VRFBeaconSession) KeyGenerated(kd KeyDataStructKeyData) (*types.Transaction, error) {
- return _VRFBeacon.Contract.KeyGenerated(&_VRFBeacon.TransactOpts, kd)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) KeyGenerated(kd KeyDataStructKeyData) (*types.Transaction, error) {
- return _VRFBeacon.Contract.KeyGenerated(&_VRFBeacon.TransactOpts, kd)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) NewKeyRequested(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "newKeyRequested")
-}
-
-func (_VRFBeacon *VRFBeaconSession) NewKeyRequested() (*types.Transaction, error) {
- return _VRFBeacon.Contract.NewKeyRequested(&_VRFBeacon.TransactOpts)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) NewKeyRequested() (*types.Transaction, error) {
- return _VRFBeacon.Contract.NewKeyRequested(&_VRFBeacon.TransactOpts)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) SetBilling(opts *bind.TransactOpts, maximumGasPrice uint64, reasonableGasPrice uint64, observationPayment uint64, transmissionPayment uint64, accountingGas *big.Int) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "setBilling", maximumGasPrice, reasonableGasPrice, observationPayment, transmissionPayment, accountingGas)
-}
-
-func (_VRFBeacon *VRFBeaconSession) SetBilling(maximumGasPrice uint64, reasonableGasPrice uint64, observationPayment uint64, transmissionPayment uint64, accountingGas *big.Int) (*types.Transaction, error) {
- return _VRFBeacon.Contract.SetBilling(&_VRFBeacon.TransactOpts, maximumGasPrice, reasonableGasPrice, observationPayment, transmissionPayment, accountingGas)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) SetBilling(maximumGasPrice uint64, reasonableGasPrice uint64, observationPayment uint64, transmissionPayment uint64, accountingGas *big.Int) (*types.Transaction, error) {
- return _VRFBeacon.Contract.SetBilling(&_VRFBeacon.TransactOpts, maximumGasPrice, reasonableGasPrice, observationPayment, transmissionPayment, accountingGas)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) SetBillingAccessController(opts *bind.TransactOpts, _billingAccessController common.Address) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "setBillingAccessController", _billingAccessController)
-}
-
-func (_VRFBeacon *VRFBeaconSession) SetBillingAccessController(_billingAccessController common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.SetBillingAccessController(&_VRFBeacon.TransactOpts, _billingAccessController)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) SetBillingAccessController(_billingAccessController common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.SetBillingAccessController(&_VRFBeacon.TransactOpts, _billingAccessController)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig)
-}
-
-func (_VRFBeacon *VRFBeaconSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) {
- return _VRFBeacon.Contract.SetConfig(&_VRFBeacon.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) {
- return _VRFBeacon.Contract.SetConfig(&_VRFBeacon.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) SetPayees(opts *bind.TransactOpts, transmitters []common.Address, payees []common.Address) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "setPayees", transmitters, payees)
-}
-
-func (_VRFBeacon *VRFBeaconSession) SetPayees(transmitters []common.Address, payees []common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.SetPayees(&_VRFBeacon.TransactOpts, transmitters, payees)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) SetPayees(transmitters []common.Address, payees []common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.SetPayees(&_VRFBeacon.TransactOpts, transmitters, payees)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "transferOwnership", to)
-}
-
-func (_VRFBeacon *VRFBeaconSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.TransferOwnership(&_VRFBeacon.TransactOpts, to)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.TransferOwnership(&_VRFBeacon.TransactOpts, to)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) TransferPayeeship(opts *bind.TransactOpts, transmitter common.Address, proposed common.Address) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "transferPayeeship", transmitter, proposed)
-}
-
-func (_VRFBeacon *VRFBeaconSession) TransferPayeeship(transmitter common.Address, proposed common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.TransferPayeeship(&_VRFBeacon.TransactOpts, transmitter, proposed)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) TransferPayeeship(transmitter common.Address, proposed common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.TransferPayeeship(&_VRFBeacon.TransactOpts, transmitter, proposed)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs)
-}
-
-func (_VRFBeacon *VRFBeaconSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) {
- return _VRFBeacon.Contract.Transmit(&_VRFBeacon.TransactOpts, reportContext, report, rs, ss, rawVs)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) {
- return _VRFBeacon.Contract.Transmit(&_VRFBeacon.TransactOpts, reportContext, report, rs, ss, rawVs)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) WithdrawFunds(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "withdrawFunds", recipient, amount)
-}
-
-func (_VRFBeacon *VRFBeaconSession) WithdrawFunds(recipient common.Address, amount *big.Int) (*types.Transaction, error) {
- return _VRFBeacon.Contract.WithdrawFunds(&_VRFBeacon.TransactOpts, recipient, amount)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) WithdrawFunds(recipient common.Address, amount *big.Int) (*types.Transaction, error) {
- return _VRFBeacon.Contract.WithdrawFunds(&_VRFBeacon.TransactOpts, recipient, amount)
-}
-
-func (_VRFBeacon *VRFBeaconTransactor) WithdrawPayment(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) {
- return _VRFBeacon.contract.Transact(opts, "withdrawPayment", transmitter)
-}
-
-func (_VRFBeacon *VRFBeaconSession) WithdrawPayment(transmitter common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.WithdrawPayment(&_VRFBeacon.TransactOpts, transmitter)
-}
-
-func (_VRFBeacon *VRFBeaconTransactorSession) WithdrawPayment(transmitter common.Address) (*types.Transaction, error) {
- return _VRFBeacon.Contract.WithdrawPayment(&_VRFBeacon.TransactOpts, transmitter)
-}
-
-type VRFBeaconBillingAccessControllerSetIterator struct {
- Event *VRFBeaconBillingAccessControllerSet
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconBillingAccessControllerSetIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconBillingAccessControllerSet)
- 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(VRFBeaconBillingAccessControllerSet)
- 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 *VRFBeaconBillingAccessControllerSetIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconBillingAccessControllerSetIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconBillingAccessControllerSet struct {
- Old common.Address
- Current common.Address
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterBillingAccessControllerSet(opts *bind.FilterOpts) (*VRFBeaconBillingAccessControllerSetIterator, error) {
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "BillingAccessControllerSet")
- if err != nil {
- return nil, err
- }
- return &VRFBeaconBillingAccessControllerSetIterator{contract: _VRFBeacon.contract, event: "BillingAccessControllerSet", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchBillingAccessControllerSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconBillingAccessControllerSet) (event.Subscription, error) {
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "BillingAccessControllerSet")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconBillingAccessControllerSet)
- if err := _VRFBeacon.contract.UnpackLog(event, "BillingAccessControllerSet", 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 (_VRFBeacon *VRFBeaconFilterer) ParseBillingAccessControllerSet(log types.Log) (*VRFBeaconBillingAccessControllerSet, error) {
- event := new(VRFBeaconBillingAccessControllerSet)
- if err := _VRFBeacon.contract.UnpackLog(event, "BillingAccessControllerSet", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconBillingSetIterator struct {
- Event *VRFBeaconBillingSet
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconBillingSetIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconBillingSet)
- 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(VRFBeaconBillingSet)
- 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 *VRFBeaconBillingSetIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconBillingSetIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconBillingSet struct {
- MaximumGasPrice uint64
- ReasonableGasPrice uint64
- ObservationPayment uint64
- TransmissionPayment uint64
- AccountingGas *big.Int
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterBillingSet(opts *bind.FilterOpts) (*VRFBeaconBillingSetIterator, error) {
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "BillingSet")
- if err != nil {
- return nil, err
- }
- return &VRFBeaconBillingSetIterator{contract: _VRFBeacon.contract, event: "BillingSet", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchBillingSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconBillingSet) (event.Subscription, error) {
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "BillingSet")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconBillingSet)
- if err := _VRFBeacon.contract.UnpackLog(event, "BillingSet", 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 (_VRFBeacon *VRFBeaconFilterer) ParseBillingSet(log types.Log) (*VRFBeaconBillingSet, error) {
- event := new(VRFBeaconBillingSet)
- if err := _VRFBeacon.contract.UnpackLog(event, "BillingSet", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconConfigSetIterator struct {
- Event *VRFBeaconConfigSet
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconConfigSetIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconConfigSet)
- 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(VRFBeaconConfigSet)
- 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 *VRFBeaconConfigSetIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconConfigSetIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconConfigSet struct {
- PreviousConfigBlockNumber uint32
- ConfigDigest [32]byte
- ConfigCount uint64
- Signers []common.Address
- Transmitters []common.Address
- F uint8
- OnchainConfig []byte
- OffchainConfigVersion uint64
- OffchainConfig []byte
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFBeaconConfigSetIterator, error) {
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "ConfigSet")
- if err != nil {
- return nil, err
- }
- return &VRFBeaconConfigSetIterator{contract: _VRFBeacon.contract, event: "ConfigSet", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconConfigSet) (event.Subscription, error) {
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "ConfigSet")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconConfigSet)
- if err := _VRFBeacon.contract.UnpackLog(event, "ConfigSet", 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 (_VRFBeacon *VRFBeaconFilterer) ParseConfigSet(log types.Log) (*VRFBeaconConfigSet, error) {
- event := new(VRFBeaconConfigSet)
- if err := _VRFBeacon.contract.UnpackLog(event, "ConfigSet", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconNewTransmissionIterator struct {
- Event *VRFBeaconNewTransmission
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconNewTransmissionIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconNewTransmission)
- 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(VRFBeaconNewTransmission)
- 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 *VRFBeaconNewTransmissionIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconNewTransmissionIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconNewTransmission struct {
- EpochAndRound *big.Int
- Transmitter common.Address
- JuelsPerFeeCoin *big.Int
- ReasonableGasPrice uint64
- ConfigDigest [32]byte
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterNewTransmission(opts *bind.FilterOpts, epochAndRound []*big.Int) (*VRFBeaconNewTransmissionIterator, error) {
-
- var epochAndRoundRule []interface{}
- for _, epochAndRoundItem := range epochAndRound {
- epochAndRoundRule = append(epochAndRoundRule, epochAndRoundItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "NewTransmission", epochAndRoundRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconNewTransmissionIterator{contract: _VRFBeacon.contract, event: "NewTransmission", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchNewTransmission(opts *bind.WatchOpts, sink chan<- *VRFBeaconNewTransmission, epochAndRound []*big.Int) (event.Subscription, error) {
-
- var epochAndRoundRule []interface{}
- for _, epochAndRoundItem := range epochAndRound {
- epochAndRoundRule = append(epochAndRoundRule, epochAndRoundItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "NewTransmission", epochAndRoundRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconNewTransmission)
- if err := _VRFBeacon.contract.UnpackLog(event, "NewTransmission", 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 (_VRFBeacon *VRFBeaconFilterer) ParseNewTransmission(log types.Log) (*VRFBeaconNewTransmission, error) {
- event := new(VRFBeaconNewTransmission)
- if err := _VRFBeacon.contract.UnpackLog(event, "NewTransmission", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconOraclePaidIterator struct {
- Event *VRFBeaconOraclePaid
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconOraclePaidIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconOraclePaid)
- 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(VRFBeaconOraclePaid)
- 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 *VRFBeaconOraclePaidIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconOraclePaidIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconOraclePaid struct {
- Transmitter common.Address
- Payee common.Address
- Amount *big.Int
- LinkToken common.Address
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterOraclePaid(opts *bind.FilterOpts, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (*VRFBeaconOraclePaidIterator, error) {
-
- var transmitterRule []interface{}
- for _, transmitterItem := range transmitter {
- transmitterRule = append(transmitterRule, transmitterItem)
- }
- var payeeRule []interface{}
- for _, payeeItem := range payee {
- payeeRule = append(payeeRule, payeeItem)
- }
-
- var linkTokenRule []interface{}
- for _, linkTokenItem := range linkToken {
- linkTokenRule = append(linkTokenRule, linkTokenItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "OraclePaid", transmitterRule, payeeRule, linkTokenRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconOraclePaidIterator{contract: _VRFBeacon.contract, event: "OraclePaid", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchOraclePaid(opts *bind.WatchOpts, sink chan<- *VRFBeaconOraclePaid, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (event.Subscription, error) {
-
- var transmitterRule []interface{}
- for _, transmitterItem := range transmitter {
- transmitterRule = append(transmitterRule, transmitterItem)
- }
- var payeeRule []interface{}
- for _, payeeItem := range payee {
- payeeRule = append(payeeRule, payeeItem)
- }
-
- var linkTokenRule []interface{}
- for _, linkTokenItem := range linkToken {
- linkTokenRule = append(linkTokenRule, linkTokenItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "OraclePaid", transmitterRule, payeeRule, linkTokenRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconOraclePaid)
- if err := _VRFBeacon.contract.UnpackLog(event, "OraclePaid", 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 (_VRFBeacon *VRFBeaconFilterer) ParseOraclePaid(log types.Log) (*VRFBeaconOraclePaid, error) {
- event := new(VRFBeaconOraclePaid)
- if err := _VRFBeacon.contract.UnpackLog(event, "OraclePaid", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconOutputsServedIterator struct {
- Event *VRFBeaconOutputsServed
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconOutputsServedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconOutputsServed)
- 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(VRFBeaconOutputsServed)
- 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 *VRFBeaconOutputsServedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconOutputsServedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconOutputsServed struct {
- RecentBlockHeight uint64
- JuelsPerFeeCoin *big.Int
- ReasonableGasPrice uint64
- OutputsServed []VRFBeaconTypesOutputServed
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterOutputsServed(opts *bind.FilterOpts) (*VRFBeaconOutputsServedIterator, error) {
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "OutputsServed")
- if err != nil {
- return nil, err
- }
- return &VRFBeaconOutputsServedIterator{contract: _VRFBeacon.contract, event: "OutputsServed", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchOutputsServed(opts *bind.WatchOpts, sink chan<- *VRFBeaconOutputsServed) (event.Subscription, error) {
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "OutputsServed")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconOutputsServed)
- if err := _VRFBeacon.contract.UnpackLog(event, "OutputsServed", 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 (_VRFBeacon *VRFBeaconFilterer) ParseOutputsServed(log types.Log) (*VRFBeaconOutputsServed, error) {
- event := new(VRFBeaconOutputsServed)
- if err := _VRFBeacon.contract.UnpackLog(event, "OutputsServed", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconOwnershipTransferRequestedIterator struct {
- Event *VRFBeaconOwnershipTransferRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconOwnershipTransferRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconOwnershipTransferRequested)
- 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(VRFBeaconOwnershipTransferRequested)
- 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 *VRFBeaconOwnershipTransferRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconOwnershipTransferRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconOwnershipTransferRequested struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFBeaconOwnershipTransferRequestedIterator, 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 := _VRFBeacon.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconOwnershipTransferRequestedIterator{contract: _VRFBeacon.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconOwnershipTransferRequested, 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 := _VRFBeacon.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(VRFBeaconOwnershipTransferRequested)
- if err := _VRFBeacon.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 (_VRFBeacon *VRFBeaconFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFBeaconOwnershipTransferRequested, error) {
- event := new(VRFBeaconOwnershipTransferRequested)
- if err := _VRFBeacon.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconOwnershipTransferredIterator struct {
- Event *VRFBeaconOwnershipTransferred
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconOwnershipTransferredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconOwnershipTransferred)
- 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(VRFBeaconOwnershipTransferred)
- 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 *VRFBeaconOwnershipTransferredIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconOwnershipTransferredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconOwnershipTransferred struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFBeaconOwnershipTransferredIterator, 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 := _VRFBeacon.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconOwnershipTransferredIterator{contract: _VRFBeacon.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFBeaconOwnershipTransferred, 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 := _VRFBeacon.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(VRFBeaconOwnershipTransferred)
- if err := _VRFBeacon.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 (_VRFBeacon *VRFBeaconFilterer) ParseOwnershipTransferred(log types.Log) (*VRFBeaconOwnershipTransferred, error) {
- event := new(VRFBeaconOwnershipTransferred)
- if err := _VRFBeacon.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconPayeeshipTransferRequestedIterator struct {
- Event *VRFBeaconPayeeshipTransferRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconPayeeshipTransferRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconPayeeshipTransferRequested)
- 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(VRFBeaconPayeeshipTransferRequested)
- 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 *VRFBeaconPayeeshipTransferRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconPayeeshipTransferRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconPayeeshipTransferRequested struct {
- Transmitter common.Address
- Current common.Address
- Proposed common.Address
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, current []common.Address, proposed []common.Address) (*VRFBeaconPayeeshipTransferRequestedIterator, error) {
-
- var transmitterRule []interface{}
- for _, transmitterItem := range transmitter {
- transmitterRule = append(transmitterRule, transmitterItem)
- }
- var currentRule []interface{}
- for _, currentItem := range current {
- currentRule = append(currentRule, currentItem)
- }
- var proposedRule []interface{}
- for _, proposedItem := range proposed {
- proposedRule = append(proposedRule, proposedItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "PayeeshipTransferRequested", transmitterRule, currentRule, proposedRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconPayeeshipTransferRequestedIterator{contract: _VRFBeacon.contract, event: "PayeeshipTransferRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconPayeeshipTransferRequested, transmitter []common.Address, current []common.Address, proposed []common.Address) (event.Subscription, error) {
-
- var transmitterRule []interface{}
- for _, transmitterItem := range transmitter {
- transmitterRule = append(transmitterRule, transmitterItem)
- }
- var currentRule []interface{}
- for _, currentItem := range current {
- currentRule = append(currentRule, currentItem)
- }
- var proposedRule []interface{}
- for _, proposedItem := range proposed {
- proposedRule = append(proposedRule, proposedItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "PayeeshipTransferRequested", transmitterRule, currentRule, proposedRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconPayeeshipTransferRequested)
- if err := _VRFBeacon.contract.UnpackLog(event, "PayeeshipTransferRequested", 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 (_VRFBeacon *VRFBeaconFilterer) ParsePayeeshipTransferRequested(log types.Log) (*VRFBeaconPayeeshipTransferRequested, error) {
- event := new(VRFBeaconPayeeshipTransferRequested)
- if err := _VRFBeacon.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconPayeeshipTransferredIterator struct {
- Event *VRFBeaconPayeeshipTransferred
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconPayeeshipTransferredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconPayeeshipTransferred)
- 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(VRFBeaconPayeeshipTransferred)
- 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 *VRFBeaconPayeeshipTransferredIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconPayeeshipTransferredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconPayeeshipTransferred struct {
- Transmitter common.Address
- Previous common.Address
- Current common.Address
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, previous []common.Address, current []common.Address) (*VRFBeaconPayeeshipTransferredIterator, error) {
-
- var transmitterRule []interface{}
- for _, transmitterItem := range transmitter {
- transmitterRule = append(transmitterRule, transmitterItem)
- }
- var previousRule []interface{}
- for _, previousItem := range previous {
- previousRule = append(previousRule, previousItem)
- }
- var currentRule []interface{}
- for _, currentItem := range current {
- currentRule = append(currentRule, currentItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "PayeeshipTransferred", transmitterRule, previousRule, currentRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconPayeeshipTransferredIterator{contract: _VRFBeacon.contract, event: "PayeeshipTransferred", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *VRFBeaconPayeeshipTransferred, transmitter []common.Address, previous []common.Address, current []common.Address) (event.Subscription, error) {
-
- var transmitterRule []interface{}
- for _, transmitterItem := range transmitter {
- transmitterRule = append(transmitterRule, transmitterItem)
- }
- var previousRule []interface{}
- for _, previousItem := range previous {
- previousRule = append(previousRule, previousItem)
- }
- var currentRule []interface{}
- for _, currentItem := range current {
- currentRule = append(currentRule, currentItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "PayeeshipTransferred", transmitterRule, previousRule, currentRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconPayeeshipTransferred)
- if err := _VRFBeacon.contract.UnpackLog(event, "PayeeshipTransferred", 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 (_VRFBeacon *VRFBeaconFilterer) ParsePayeeshipTransferred(log types.Log) (*VRFBeaconPayeeshipTransferred, error) {
- event := new(VRFBeaconPayeeshipTransferred)
- if err := _VRFBeacon.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconRandomWordsFulfilledIterator struct {
- Event *VRFBeaconRandomWordsFulfilled
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconRandomWordsFulfilledIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconRandomWordsFulfilled)
- 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(VRFBeaconRandomWordsFulfilled)
- 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 *VRFBeaconRandomWordsFulfilledIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconRandomWordsFulfilledIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconRandomWordsFulfilled struct {
- RequestIDs []*big.Int
- SuccessfulFulfillment []byte
- TruncatedErrorData [][]byte
- SubBalances []*big.Int
- SubIDs []*big.Int
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts) (*VRFBeaconRandomWordsFulfilledIterator, error) {
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "RandomWordsFulfilled")
- if err != nil {
- return nil, err
- }
- return &VRFBeaconRandomWordsFulfilledIterator{contract: _VRFBeacon.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomWordsFulfilled) (event.Subscription, error) {
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "RandomWordsFulfilled")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconRandomWordsFulfilled)
- if err := _VRFBeacon.contract.UnpackLog(event, "RandomWordsFulfilled", 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 (_VRFBeacon *VRFBeaconFilterer) ParseRandomWordsFulfilled(log types.Log) (*VRFBeaconRandomWordsFulfilled, error) {
- event := new(VRFBeaconRandomWordsFulfilled)
- if err := _VRFBeacon.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconRandomnessFulfillmentRequestedIterator struct {
- Event *VRFBeaconRandomnessFulfillmentRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconRandomnessFulfillmentRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconRandomnessFulfillmentRequested)
- 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(VRFBeaconRandomnessFulfillmentRequested)
- 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 *VRFBeaconRandomnessFulfillmentRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconRandomnessFulfillmentRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconRandomnessFulfillmentRequested struct {
- RequestID *big.Int
- Requester common.Address
- NextBeaconOutputHeight uint64
- ConfDelay *big.Int
- SubID *big.Int
- NumWords uint16
- GasAllowance uint32
- GasPrice *big.Int
- WeiPerUnitLink *big.Int
- Arguments []byte
- CostJuels *big.Int
- NewSubBalance *big.Int
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterRandomnessFulfillmentRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFBeaconRandomnessFulfillmentRequestedIterator, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "RandomnessFulfillmentRequested", requestIDRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconRandomnessFulfillmentRequestedIterator{contract: _VRFBeacon.contract, event: "RandomnessFulfillmentRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchRandomnessFulfillmentRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessFulfillmentRequested, requestID []*big.Int) (event.Subscription, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "RandomnessFulfillmentRequested", requestIDRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconRandomnessFulfillmentRequested)
- if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessFulfillmentRequested", 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 (_VRFBeacon *VRFBeaconFilterer) ParseRandomnessFulfillmentRequested(log types.Log) (*VRFBeaconRandomnessFulfillmentRequested, error) {
- event := new(VRFBeaconRandomnessFulfillmentRequested)
- if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessFulfillmentRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconRandomnessRedeemedIterator struct {
- Event *VRFBeaconRandomnessRedeemed
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconRandomnessRedeemedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconRandomnessRedeemed)
- 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(VRFBeaconRandomnessRedeemed)
- 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 *VRFBeaconRandomnessRedeemedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconRandomnessRedeemedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconRandomnessRedeemed struct {
- RequestID *big.Int
- Requester common.Address
- SubID *big.Int
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterRandomnessRedeemed(opts *bind.FilterOpts, requestID []*big.Int, requester []common.Address) (*VRFBeaconRandomnessRedeemedIterator, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
- var requesterRule []interface{}
- for _, requesterItem := range requester {
- requesterRule = append(requesterRule, requesterItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "RandomnessRedeemed", requestIDRule, requesterRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconRandomnessRedeemedIterator{contract: _VRFBeacon.contract, event: "RandomnessRedeemed", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchRandomnessRedeemed(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessRedeemed, requestID []*big.Int, requester []common.Address) (event.Subscription, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
- var requesterRule []interface{}
- for _, requesterItem := range requester {
- requesterRule = append(requesterRule, requesterItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "RandomnessRedeemed", requestIDRule, requesterRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconRandomnessRedeemed)
- if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessRedeemed", 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 (_VRFBeacon *VRFBeaconFilterer) ParseRandomnessRedeemed(log types.Log) (*VRFBeaconRandomnessRedeemed, error) {
- event := new(VRFBeaconRandomnessRedeemed)
- if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessRedeemed", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFBeaconRandomnessRequestedIterator struct {
- Event *VRFBeaconRandomnessRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFBeaconRandomnessRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFBeaconRandomnessRequested)
- 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(VRFBeaconRandomnessRequested)
- 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 *VRFBeaconRandomnessRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFBeaconRandomnessRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFBeaconRandomnessRequested struct {
- RequestID *big.Int
- Requester common.Address
- NextBeaconOutputHeight uint64
- ConfDelay *big.Int
- SubID *big.Int
- NumWords uint16
- CostJuels *big.Int
- NewSubBalance *big.Int
- Raw types.Log
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) FilterRandomnessRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFBeaconRandomnessRequestedIterator, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "RandomnessRequested", requestIDRule)
- if err != nil {
- return nil, err
- }
- return &VRFBeaconRandomnessRequestedIterator{contract: _VRFBeacon.contract, event: "RandomnessRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VRFBeacon *VRFBeaconFilterer) WatchRandomnessRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessRequested, requestID []*big.Int) (event.Subscription, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
-
- logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "RandomnessRequested", requestIDRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFBeaconRandomnessRequested)
- if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessRequested", 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 (_VRFBeacon *VRFBeaconFilterer) ParseRandomnessRequested(log types.Log) (*VRFBeaconRandomnessRequested, error) {
- event := new(VRFBeaconRandomnessRequested)
- if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type GetBilling struct {
- MaximumGasPrice uint64
- ReasonableGasPrice uint64
- ObservationPayment uint64
- TransmissionPayment uint64
- AccountingGas *big.Int
-}
-type LatestConfigDetails struct {
- ConfigCount uint32
- BlockNumber uint32
- ConfigDigest [32]byte
-}
-type LatestConfigDigestAndEpoch struct {
- ScanLogs bool
- ConfigDigest [32]byte
- Epoch uint32
-}
-
-func (_VRFBeacon *VRFBeacon) ParseLog(log types.Log) (generated.AbigenLog, error) {
- switch log.Topics[0] {
- case _VRFBeacon.abi.Events["BillingAccessControllerSet"].ID:
- return _VRFBeacon.ParseBillingAccessControllerSet(log)
- case _VRFBeacon.abi.Events["BillingSet"].ID:
- return _VRFBeacon.ParseBillingSet(log)
- case _VRFBeacon.abi.Events["ConfigSet"].ID:
- return _VRFBeacon.ParseConfigSet(log)
- case _VRFBeacon.abi.Events["NewTransmission"].ID:
- return _VRFBeacon.ParseNewTransmission(log)
- case _VRFBeacon.abi.Events["OraclePaid"].ID:
- return _VRFBeacon.ParseOraclePaid(log)
- case _VRFBeacon.abi.Events["OutputsServed"].ID:
- return _VRFBeacon.ParseOutputsServed(log)
- case _VRFBeacon.abi.Events["OwnershipTransferRequested"].ID:
- return _VRFBeacon.ParseOwnershipTransferRequested(log)
- case _VRFBeacon.abi.Events["OwnershipTransferred"].ID:
- return _VRFBeacon.ParseOwnershipTransferred(log)
- case _VRFBeacon.abi.Events["PayeeshipTransferRequested"].ID:
- return _VRFBeacon.ParsePayeeshipTransferRequested(log)
- case _VRFBeacon.abi.Events["PayeeshipTransferred"].ID:
- return _VRFBeacon.ParsePayeeshipTransferred(log)
- case _VRFBeacon.abi.Events["RandomWordsFulfilled"].ID:
- return _VRFBeacon.ParseRandomWordsFulfilled(log)
- case _VRFBeacon.abi.Events["RandomnessFulfillmentRequested"].ID:
- return _VRFBeacon.ParseRandomnessFulfillmentRequested(log)
- case _VRFBeacon.abi.Events["RandomnessRedeemed"].ID:
- return _VRFBeacon.ParseRandomnessRedeemed(log)
- case _VRFBeacon.abi.Events["RandomnessRequested"].ID:
- return _VRFBeacon.ParseRandomnessRequested(log)
-
- default:
- return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
- }
-}
-
-func (VRFBeaconBillingAccessControllerSet) Topic() common.Hash {
- return common.HexToHash("0x793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d48912")
-}
-
-func (VRFBeaconBillingSet) Topic() common.Hash {
- return common.HexToHash("0x49275ddcdfc9c0519b3d094308c8bf675f06070a754ce90c152163cb6e66e8a0")
-}
-
-func (VRFBeaconConfigSet) Topic() common.Hash {
- return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05")
-}
-
-func (VRFBeaconNewTransmission) Topic() common.Hash {
- return common.HexToHash("0xfc3c7a7927e878a0fca37c904953c3c75cee3ca1d1640184a0ab1c65eec62743")
-}
-
-func (VRFBeaconOraclePaid) Topic() common.Hash {
- return common.HexToHash("0xd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c")
-}
-
-func (VRFBeaconOutputsServed) Topic() common.Hash {
- return common.HexToHash("0xf10ea936d00579b4c52035ee33bf46929646b3aa87554c565d8fb2c7aa549c44")
-}
-
-func (VRFBeaconOwnershipTransferRequested) Topic() common.Hash {
- return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
-}
-
-func (VRFBeaconOwnershipTransferred) Topic() common.Hash {
- return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
-}
-
-func (VRFBeaconPayeeshipTransferRequested) Topic() common.Hash {
- return common.HexToHash("0x84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e38367")
-}
-
-func (VRFBeaconPayeeshipTransferred) Topic() common.Hash {
- return common.HexToHash("0x78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b3")
-}
-
-func (VRFBeaconRandomWordsFulfilled) Topic() common.Hash {
- return common.HexToHash("0x8f79f730779e875ce76c428039cc2052b5b5918c2a55c598fab251c1198aec54")
-}
-
-func (VRFBeaconRandomnessFulfillmentRequested) Topic() common.Hash {
- return common.HexToHash("0x01872fb9c7d6d68af06a17347935e04412da302a377224c205e672c26e18c37f")
-}
-
-func (VRFBeaconRandomnessRedeemed) Topic() common.Hash {
- return common.HexToHash("0x16f3f633197fafab10a5df69e6f3f2f7f20092f08d8d47de0a91c0f4b96a1a25")
-}
-
-func (VRFBeaconRandomnessRequested) Topic() common.Hash {
- return common.HexToHash("0xb7933fba96b6b452eb44f99fdc08052a45dff82363d59abaff0456931c3d2459")
-}
-
-func (_VRFBeacon *VRFBeacon) Address() common.Address {
- return _VRFBeacon.address
-}
-
-type VRFBeaconInterface interface {
- NUMCONFDELAYS(opts *bind.CallOpts) (uint8, error)
-
- GetBilling(opts *bind.CallOpts) (GetBilling,
-
- error)
-
- GetBillingAccessController(opts *bind.CallOpts) (common.Address, error)
-
- ICoordinator(opts *bind.CallOpts) (common.Address, error)
-
- ILink(opts *bind.CallOpts) (common.Address, error)
-
- LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails,
-
- error)
-
- LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch,
-
- error)
-
- LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error)
-
- OwedPayment(opts *bind.CallOpts, transmitterAddress common.Address) (*big.Int, error)
-
- Owner(opts *bind.CallOpts) (common.Address, error)
-
- SKeyID(opts *bind.CallOpts) ([32]byte, error)
-
- SKeyProvider(opts *bind.CallOpts) (common.Address, error)
-
- SProvingKeyHash(opts *bind.CallOpts) ([32]byte, error)
-
- TypeAndVersion(opts *bind.CallOpts) (string, error)
-
- AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
-
- AcceptPayeeship(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error)
-
- ExposeType(opts *bind.TransactOpts, arg0 VRFBeaconReportReport) (*types.Transaction, error)
-
- KeyGenerated(opts *bind.TransactOpts, kd KeyDataStructKeyData) (*types.Transaction, error)
-
- NewKeyRequested(opts *bind.TransactOpts) (*types.Transaction, error)
-
- SetBilling(opts *bind.TransactOpts, maximumGasPrice uint64, reasonableGasPrice uint64, observationPayment uint64, transmissionPayment uint64, accountingGas *big.Int) (*types.Transaction, error)
-
- SetBillingAccessController(opts *bind.TransactOpts, _billingAccessController common.Address) (*types.Transaction, error)
-
- SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error)
-
- SetPayees(opts *bind.TransactOpts, transmitters []common.Address, payees []common.Address) (*types.Transaction, error)
-
- TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
-
- TransferPayeeship(opts *bind.TransactOpts, transmitter common.Address, proposed common.Address) (*types.Transaction, error)
-
- Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error)
-
- WithdrawFunds(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error)
-
- WithdrawPayment(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error)
-
- FilterBillingAccessControllerSet(opts *bind.FilterOpts) (*VRFBeaconBillingAccessControllerSetIterator, error)
-
- WatchBillingAccessControllerSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconBillingAccessControllerSet) (event.Subscription, error)
-
- ParseBillingAccessControllerSet(log types.Log) (*VRFBeaconBillingAccessControllerSet, error)
-
- FilterBillingSet(opts *bind.FilterOpts) (*VRFBeaconBillingSetIterator, error)
-
- WatchBillingSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconBillingSet) (event.Subscription, error)
-
- ParseBillingSet(log types.Log) (*VRFBeaconBillingSet, error)
-
- FilterConfigSet(opts *bind.FilterOpts) (*VRFBeaconConfigSetIterator, error)
-
- WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconConfigSet) (event.Subscription, error)
-
- ParseConfigSet(log types.Log) (*VRFBeaconConfigSet, error)
-
- FilterNewTransmission(opts *bind.FilterOpts, epochAndRound []*big.Int) (*VRFBeaconNewTransmissionIterator, error)
-
- WatchNewTransmission(opts *bind.WatchOpts, sink chan<- *VRFBeaconNewTransmission, epochAndRound []*big.Int) (event.Subscription, error)
-
- ParseNewTransmission(log types.Log) (*VRFBeaconNewTransmission, error)
-
- FilterOraclePaid(opts *bind.FilterOpts, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (*VRFBeaconOraclePaidIterator, error)
-
- WatchOraclePaid(opts *bind.WatchOpts, sink chan<- *VRFBeaconOraclePaid, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (event.Subscription, error)
-
- ParseOraclePaid(log types.Log) (*VRFBeaconOraclePaid, error)
-
- FilterOutputsServed(opts *bind.FilterOpts) (*VRFBeaconOutputsServedIterator, error)
-
- WatchOutputsServed(opts *bind.WatchOpts, sink chan<- *VRFBeaconOutputsServed) (event.Subscription, error)
-
- ParseOutputsServed(log types.Log) (*VRFBeaconOutputsServed, error)
-
- FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFBeaconOwnershipTransferRequestedIterator, error)
-
- WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferRequested(log types.Log) (*VRFBeaconOwnershipTransferRequested, error)
-
- FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFBeaconOwnershipTransferredIterator, error)
-
- WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFBeaconOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferred(log types.Log) (*VRFBeaconOwnershipTransferred, error)
-
- FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, current []common.Address, proposed []common.Address) (*VRFBeaconPayeeshipTransferRequestedIterator, error)
-
- WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconPayeeshipTransferRequested, transmitter []common.Address, current []common.Address, proposed []common.Address) (event.Subscription, error)
-
- ParsePayeeshipTransferRequested(log types.Log) (*VRFBeaconPayeeshipTransferRequested, error)
-
- FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, previous []common.Address, current []common.Address) (*VRFBeaconPayeeshipTransferredIterator, error)
-
- WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *VRFBeaconPayeeshipTransferred, transmitter []common.Address, previous []common.Address, current []common.Address) (event.Subscription, error)
-
- ParsePayeeshipTransferred(log types.Log) (*VRFBeaconPayeeshipTransferred, error)
-
- FilterRandomWordsFulfilled(opts *bind.FilterOpts) (*VRFBeaconRandomWordsFulfilledIterator, error)
-
- WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomWordsFulfilled) (event.Subscription, error)
-
- ParseRandomWordsFulfilled(log types.Log) (*VRFBeaconRandomWordsFulfilled, error)
-
- FilterRandomnessFulfillmentRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFBeaconRandomnessFulfillmentRequestedIterator, error)
-
- WatchRandomnessFulfillmentRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessFulfillmentRequested, requestID []*big.Int) (event.Subscription, error)
-
- ParseRandomnessFulfillmentRequested(log types.Log) (*VRFBeaconRandomnessFulfillmentRequested, error)
-
- FilterRandomnessRedeemed(opts *bind.FilterOpts, requestID []*big.Int, requester []common.Address) (*VRFBeaconRandomnessRedeemedIterator, error)
-
- WatchRandomnessRedeemed(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessRedeemed, requestID []*big.Int, requester []common.Address) (event.Subscription, error)
-
- ParseRandomnessRedeemed(log types.Log) (*VRFBeaconRandomnessRedeemed, error)
-
- FilterRandomnessRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFBeaconRandomnessRequestedIterator, error)
-
- WatchRandomnessRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessRequested, requestID []*big.Int) (event.Subscription, error)
-
- ParseRandomnessRequested(log types.Log) (*VRFBeaconRandomnessRequested, error)
-
- ParseLog(log types.Log) (generated.AbigenLog, error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer/vrf_beacon_consumer.go b/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer/vrf_beacon_consumer.go
deleted file mode 100644
index edc4ec6556d..00000000000
--- a/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer/vrf_beacon_consumer.go
+++ /dev/null
@@ -1,1034 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package vrf_beacon_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 BeaconVRFConsumerMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"shouldFail\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"beaconPeriodBlocks\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"MustBeCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeOwnerOrCoordinator\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorUpdated\",\"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\":[],\"name\":\"fail\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_beaconPeriodBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_ReceivedRandomnessByRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_arguments\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_mostRecentRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_myBeaconRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"slotNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"\",\"type\":\"uint24\"}],\"name\":\"s_requestsIDs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"shouldFail\",\"type\":\"bool\"}],\"name\":\"setFail\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"reqId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"height\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"delay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"}],\"name\":\"storeBeaconRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"testRedeemRandomness\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelayArg\",\"type\":\"uint24\"}],\"name\":\"testRequestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"}],\"name\":\"testRequestRandomnessFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60806040523480156200001157600080fd5b50604051620018db380380620018db8339810160408190526200003491620001aa565b8233806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620000ff565b5050600280546001600160a01b0319166001600160a01b03939093169290921790915550600b805460ff191692151592909217909155600c555062000201565b336001600160a01b03821603620001595760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080600060608486031215620001c057600080fd5b83516001600160a01b0381168114620001d857600080fd5b60208501519093508015158114620001ef57600080fd5b80925050604084015190509250925092565b6116ca80620002116000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c8063a9cc4718116100cd578063ea7502ab11610081578063f2fde38b11610066578063f2fde38b1461031f578063f6eaffc814610332578063ffe97ca41461034557600080fd5b8063ea7502ab14610303578063f08c5daa1461031657600080fd5b8063cd0593df116100b2578063cd0593df146102d4578063d0705f04146102dd578063d21ea8fd146102f057600080fd5b8063a9cc4718146102a4578063c6d61301146102c157600080fd5b80637716cdaa116101245780638da5cb5b116101095780638da5cb5b1461022a5780638ea98117146102525780639d7694021461026557600080fd5b80637716cdaa1461020d57806379ba50971461022257600080fd5b8063689b77ab11610155578063689b77ab146101c45780636df57cc3146101cd578063706da1ca146101e057600080fd5b8063341867a2146101715780635f15cccc14610186575b600080fd5b61018461017f366004610e87565b6103f8565b005b6101b1610194366004610ec1565b600460209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6101b160085481565b6101846101db366004610eff565b6104ed565b6009546101f49067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101bb565b610215610628565b6040516101bb9190610fa9565b6101846106b6565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bb565b610184610260366004610fc3565b6107b8565b610184610273366004610ff9565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600b546102b19060ff1681565b60405190151581526020016101bb565b6101b16102cf36600461101b565b61089e565b6101b1600c5481565b6101b16102eb366004610e87565b6109a8565b6101846102fe366004611187565b6109d9565b6101b1610311366004611250565b610a3a565b6101b1600a5481565b61018461032d366004610fc3565b610b4a565b6101b16103403660046112d4565b610b5e565b6103ae6103533660046112d4565b60056020526000908152604090205463ffffffff811690640100000000810462ffffff1690670100000000000000810461ffff16906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1684565b6040805163ffffffff909516855262ffffff909316602085015261ffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff1660608201526080016101bb565b60025460408051602081018252600080825291517facfc6cdd000000000000000000000000000000000000000000000000000000008152919273ffffffffffffffffffffffffffffffffffffffff169163acfc6cdd9161045e91879187916004016112ed565b6000604051808303816000875af115801561047d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526104c39190810190611315565b600083815260066020908152604090912082519293506104e7929091840190610e27565b50505050565b600083815260046020908152604080832062ffffff861684529091528120859055600c5461051b9085611404565b6040805160808101825263ffffffff928316815262ffffff958616602080830191825261ffff968716838501908152306060850190815260009b8c526005909252939099209151825491519351995173ffffffffffffffffffffffffffffffffffffffff166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff9a90971667010000000000000002999099167fffffff00000000000000000000000000000000000000000000ffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009091169890931697909717919091171692909217179092555050565b6007805461063590611418565b80601f016020809104026020016040519081016040528092919081815260200182805461066190611418565b80156106ae5780601f10610683576101008083540402835291602001916106ae565b820191906000526020600020905b81548152906001019060200180831161069157829003601f168201915b505050505081565b60015473ffffffffffffffffffffffffffffffffffffffff16331461073c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906107f8575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561082f576040517fd4e06fd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fc258faa9a17ddfdf4130b4acff63a289202e7d5f9e42f366add65368575486bc90600090a250565b600080600c546108ac610b7f565b6108b6919061146b565b9050600081600c546108c6610b7f565b6108d0919061147f565b6108da9190611498565b60025460408051602081018252600080825291517f4ffac83a000000000000000000000000000000000000000000000000000000008152939450909273ffffffffffffffffffffffffffffffffffffffff90921691634ffac83a91610948918a918c918b91906004016114ab565b6020604051808303816000875af1158015610967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b91906114e3565b90506109998183878a6104ed565b60088190559695505050505050565b600660205281600052604060002081815481106109c457600080fd5b90600052602060002001600091509150505481565b60025473ffffffffffffffffffffffffffffffffffffffff163314610a2a576040517f66bf9c7200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a35838383610c16565b505050565b600080600c54610a48610b7f565b610a52919061146b565b9050600081600c54610a62610b7f565b610a6c919061147f565b610a769190611498565b60025460408051602081018252600080825291517fdb972c8b000000000000000000000000000000000000000000000000000000008152939450909273ffffffffffffffffffffffffffffffffffffffff9092169163db972c8b91610ae8918d918d918d918d918d91906004016114fc565b6020604051808303816000875af1158015610b07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2b91906114e3565b9050610b398183898b6104ed565b600881905598975050505050505050565b610b52610caf565b610b5b81610d32565b50565b60038181548110610b6e57600080fd5b600091825260209091200154905081565b60004661a4b1811480610b94575062066eed81145b15610c0f57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0991906114e3565b91505090565b4391505090565b600b5460ff1615610c83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f206661696c656420696e2066756c66696c6c52616e646f6d576f7264730000006044820152606401610733565b60008381526006602090815260409091208351610ca292850190610e27565b5060076104e782826115a3565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610733565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610db1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610733565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610e62579160200282015b82811115610e62578251825591602001919060010190610e47565b50610e6e929150610e72565b5090565b5b80821115610e6e5760008155600101610e73565b60008060408385031215610e9a57600080fd5b50508035926020909101359150565b803562ffffff81168114610ebc57600080fd5b919050565b60008060408385031215610ed457600080fd5b82359150610ee460208401610ea9565b90509250929050565b803561ffff81168114610ebc57600080fd5b60008060008060808587031215610f1557600080fd5b8435935060208501359250610f2c60408601610ea9565b9150610f3a60608601610eed565b905092959194509250565b6000815180845260005b81811015610f6b57602081850181015186830182015201610f4f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610fbc6020830184610f45565b9392505050565b600060208284031215610fd557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610fbc57600080fd5b60006020828403121561100b57600080fd5b81358015158114610fbc57600080fd5b60008060006060848603121561103057600080fd5b61103984610eed565b92506020840135915061104e60408501610ea9565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156110cd576110cd611057565b604052919050565b600067ffffffffffffffff8211156110ef576110ef611057565b5060051b60200190565b600082601f83011261110a57600080fd5b813567ffffffffffffffff81111561112457611124611057565b61115560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611086565b81815284602083860101111561116a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561119c57600080fd5b8335925060208085013567ffffffffffffffff808211156111bc57600080fd5b818701915087601f8301126111d057600080fd5b81356111e36111de826110d5565b611086565b81815260059190911b8301840190848101908a83111561120257600080fd5b938501935b8285101561122057843582529385019390850190611207565b96505050604087013592508083111561123857600080fd5b5050611246868287016110f9565b9150509250925092565b600080600080600060a0868803121561126857600080fd5b8535945061127860208701610eed565b935061128660408701610ea9565b9250606086013563ffffffff8116811461129f57600080fd5b9150608086013567ffffffffffffffff8111156112bb57600080fd5b6112c7888289016110f9565b9150509295509295909350565b6000602082840312156112e657600080fd5b5035919050565b83815282602082015260606040820152600061130c6060830184610f45565b95945050505050565b6000602080838503121561132857600080fd5b825167ffffffffffffffff81111561133f57600080fd5b8301601f8101851361135057600080fd5b805161135e6111de826110d5565b81815260059190911b8201830190838101908783111561137d57600080fd5b928401925b8284101561139b57835182529284019290840190611382565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082611413576114136113a6565b500490565b600181811c9082168061142c57607f821691505b602082108103611465577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008261147a5761147a6113a6565b500690565b80820180821115611492576114926113d5565b92915050565b81810381811115611492576114926113d5565b84815261ffff8416602082015262ffffff831660408201526080606082015260006114d96080830184610f45565b9695505050505050565b6000602082840312156114f557600080fd5b5051919050565b86815261ffff8616602082015262ffffff8516604082015263ffffffff8416606082015260c06080820152600061153660c0830185610f45565b82810360a08401526115488185610f45565b9998505050505050505050565b601f821115610a3557600081815260208120601f850160051c8101602086101561157c5750805b601f850160051c820191505b8181101561159b57828155600101611588565b505050505050565b815167ffffffffffffffff8111156115bd576115bd611057565b6115d1816115cb8454611418565b84611555565b602080601f83116001811461162457600084156115ee5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561159b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561167157888601518255948401946001909101908401611652565b50858210156116ad57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000813000a",
-}
-
-var BeaconVRFConsumerABI = BeaconVRFConsumerMetaData.ABI
-
-var BeaconVRFConsumerBin = BeaconVRFConsumerMetaData.Bin
-
-func DeployBeaconVRFConsumer(auth *bind.TransactOpts, backend bind.ContractBackend, coordinator common.Address, shouldFail bool, beaconPeriodBlocks *big.Int) (common.Address, *types.Transaction, *BeaconVRFConsumer, error) {
- parsed, err := BeaconVRFConsumerMetaData.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(BeaconVRFConsumerBin), backend, coordinator, shouldFail, beaconPeriodBlocks)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &BeaconVRFConsumer{BeaconVRFConsumerCaller: BeaconVRFConsumerCaller{contract: contract}, BeaconVRFConsumerTransactor: BeaconVRFConsumerTransactor{contract: contract}, BeaconVRFConsumerFilterer: BeaconVRFConsumerFilterer{contract: contract}}, nil
-}
-
-type BeaconVRFConsumer struct {
- address common.Address
- abi abi.ABI
- BeaconVRFConsumerCaller
- BeaconVRFConsumerTransactor
- BeaconVRFConsumerFilterer
-}
-
-type BeaconVRFConsumerCaller struct {
- contract *bind.BoundContract
-}
-
-type BeaconVRFConsumerTransactor struct {
- contract *bind.BoundContract
-}
-
-type BeaconVRFConsumerFilterer struct {
- contract *bind.BoundContract
-}
-
-type BeaconVRFConsumerSession struct {
- Contract *BeaconVRFConsumer
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type BeaconVRFConsumerCallerSession struct {
- Contract *BeaconVRFConsumerCaller
- CallOpts bind.CallOpts
-}
-
-type BeaconVRFConsumerTransactorSession struct {
- Contract *BeaconVRFConsumerTransactor
- TransactOpts bind.TransactOpts
-}
-
-type BeaconVRFConsumerRaw struct {
- Contract *BeaconVRFConsumer
-}
-
-type BeaconVRFConsumerCallerRaw struct {
- Contract *BeaconVRFConsumerCaller
-}
-
-type BeaconVRFConsumerTransactorRaw struct {
- Contract *BeaconVRFConsumerTransactor
-}
-
-func NewBeaconVRFConsumer(address common.Address, backend bind.ContractBackend) (*BeaconVRFConsumer, error) {
- abi, err := abi.JSON(strings.NewReader(BeaconVRFConsumerABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindBeaconVRFConsumer(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &BeaconVRFConsumer{address: address, abi: abi, BeaconVRFConsumerCaller: BeaconVRFConsumerCaller{contract: contract}, BeaconVRFConsumerTransactor: BeaconVRFConsumerTransactor{contract: contract}, BeaconVRFConsumerFilterer: BeaconVRFConsumerFilterer{contract: contract}}, nil
-}
-
-func NewBeaconVRFConsumerCaller(address common.Address, caller bind.ContractCaller) (*BeaconVRFConsumerCaller, error) {
- contract, err := bindBeaconVRFConsumer(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &BeaconVRFConsumerCaller{contract: contract}, nil
-}
-
-func NewBeaconVRFConsumerTransactor(address common.Address, transactor bind.ContractTransactor) (*BeaconVRFConsumerTransactor, error) {
- contract, err := bindBeaconVRFConsumer(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &BeaconVRFConsumerTransactor{contract: contract}, nil
-}
-
-func NewBeaconVRFConsumerFilterer(address common.Address, filterer bind.ContractFilterer) (*BeaconVRFConsumerFilterer, error) {
- contract, err := bindBeaconVRFConsumer(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &BeaconVRFConsumerFilterer{contract: contract}, nil
-}
-
-func bindBeaconVRFConsumer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := BeaconVRFConsumerMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _BeaconVRFConsumer.Contract.BeaconVRFConsumerCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.BeaconVRFConsumerTransactor.contract.Transfer(opts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.BeaconVRFConsumerTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _BeaconVRFConsumer.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.contract.Transfer(opts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) Fail(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "fail")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) Fail() (bool, error) {
- return _BeaconVRFConsumer.Contract.Fail(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) Fail() (bool, error) {
- return _BeaconVRFConsumer.Contract.Fail(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "i_beaconPeriodBlocks")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) IBeaconPeriodBlocks() (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.IBeaconPeriodBlocks(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) IBeaconPeriodBlocks() (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.IBeaconPeriodBlocks(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.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 (_BeaconVRFConsumer *BeaconVRFConsumerSession) Owner() (common.Address, error) {
- return _BeaconVRFConsumer.Contract.Owner(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) Owner() (common.Address, error) {
- return _BeaconVRFConsumer.Contract.Owner(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SReceivedRandomnessByRequestID(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_ReceivedRandomnessByRequestID", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SReceivedRandomnessByRequestID(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SReceivedRandomnessByRequestID(&_BeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SReceivedRandomnessByRequestID(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SReceivedRandomnessByRequestID(&_BeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SArguments(opts *bind.CallOpts) ([]byte, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_arguments")
-
- if err != nil {
- return *new([]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SArguments() ([]byte, error) {
- return _BeaconVRFConsumer.Contract.SArguments(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SArguments() ([]byte, error) {
- return _BeaconVRFConsumer.Contract.SArguments(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SGasAvailable(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_gasAvailable")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SGasAvailable() (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SGasAvailable(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SGasAvailable() (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SGasAvailable(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SMostRecentRequestID(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_mostRecentRequestID")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SMostRecentRequestID() (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SMostRecentRequestID(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SMostRecentRequestID() (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SMostRecentRequestID(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SMyBeaconRequests(opts *bind.CallOpts, arg0 *big.Int) (SMyBeaconRequests,
-
- error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_myBeaconRequests", arg0)
-
- outstruct := new(SMyBeaconRequests)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.SlotNumber = *abi.ConvertType(out[0], new(uint32)).(*uint32)
- outstruct.ConfirmationDelay = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
- outstruct.NumWords = *abi.ConvertType(out[2], new(uint16)).(*uint16)
- outstruct.Requester = *abi.ConvertType(out[3], new(common.Address)).(*common.Address)
-
- return *outstruct, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SMyBeaconRequests(arg0 *big.Int) (SMyBeaconRequests,
-
- error) {
- return _BeaconVRFConsumer.Contract.SMyBeaconRequests(&_BeaconVRFConsumer.CallOpts, arg0)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SMyBeaconRequests(arg0 *big.Int) (SMyBeaconRequests,
-
- error) {
- return _BeaconVRFConsumer.Contract.SMyBeaconRequests(&_BeaconVRFConsumer.CallOpts, arg0)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SRandomWords(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_randomWords", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SRandomWords(arg0 *big.Int) (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SRandomWords(&_BeaconVRFConsumer.CallOpts, arg0)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SRandomWords(arg0 *big.Int) (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SRandomWords(&_BeaconVRFConsumer.CallOpts, arg0)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SRequestsIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_requestsIDs", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SRequestsIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SRequestsIDs(&_BeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SRequestsIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _BeaconVRFConsumer.Contract.SRequestsIDs(&_BeaconVRFConsumer.CallOpts, arg0, arg1)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SSubId(opts *bind.CallOpts) (uint64, error) {
- var out []interface{}
- err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_subId")
-
- if err != nil {
- return *new(uint64), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
-
- return out0, err
-
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SSubId() (uint64, error) {
- return _BeaconVRFConsumer.Contract.SSubId(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SSubId() (uint64, error) {
- return _BeaconVRFConsumer.Contract.SSubId(&_BeaconVRFConsumer.CallOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "acceptOwnership")
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) AcceptOwnership() (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.AcceptOwnership(&_BeaconVRFConsumer.TransactOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) AcceptOwnership() (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.AcceptOwnership(&_BeaconVRFConsumer.TransactOpts)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) RawFulfillRandomWords(opts *bind.TransactOpts, requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "rawFulfillRandomWords", requestID, randomWords, arguments)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) RawFulfillRandomWords(requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.RawFulfillRandomWords(&_BeaconVRFConsumer.TransactOpts, requestID, randomWords, arguments)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) RawFulfillRandomWords(requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.RawFulfillRandomWords(&_BeaconVRFConsumer.TransactOpts, requestID, randomWords, arguments)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) SetCoordinator(opts *bind.TransactOpts, coordinator common.Address) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "setCoordinator", coordinator)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SetCoordinator(coordinator common.Address) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.SetCoordinator(&_BeaconVRFConsumer.TransactOpts, coordinator)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) SetCoordinator(coordinator common.Address) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.SetCoordinator(&_BeaconVRFConsumer.TransactOpts, coordinator)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) SetFail(opts *bind.TransactOpts, shouldFail bool) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "setFail", shouldFail)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SetFail(shouldFail bool) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.SetFail(&_BeaconVRFConsumer.TransactOpts, shouldFail)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) SetFail(shouldFail bool) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.SetFail(&_BeaconVRFConsumer.TransactOpts, shouldFail)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) StoreBeaconRequest(opts *bind.TransactOpts, reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "storeBeaconRequest", reqId, height, delay, numWords)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) StoreBeaconRequest(reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.StoreBeaconRequest(&_BeaconVRFConsumer.TransactOpts, reqId, height, delay, numWords)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) StoreBeaconRequest(reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.StoreBeaconRequest(&_BeaconVRFConsumer.TransactOpts, reqId, height, delay, numWords)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) TestRedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "testRedeemRandomness", subID, requestID)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) TestRedeemRandomness(subID *big.Int, requestID *big.Int) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.TestRedeemRandomness(&_BeaconVRFConsumer.TransactOpts, subID, requestID)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) TestRedeemRandomness(subID *big.Int, requestID *big.Int) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.TestRedeemRandomness(&_BeaconVRFConsumer.TransactOpts, subID, requestID)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) TestRequestRandomness(opts *bind.TransactOpts, numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "testRequestRandomness", numWords, subID, confirmationDelayArg)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) TestRequestRandomness(numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.TestRequestRandomness(&_BeaconVRFConsumer.TransactOpts, numWords, subID, confirmationDelayArg)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) TestRequestRandomness(numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.TestRequestRandomness(&_BeaconVRFConsumer.TransactOpts, numWords, subID, confirmationDelayArg)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) TestRequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "testRequestRandomnessFulfillment", subID, numWords, confDelay, callbackGasLimit, arguments)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) TestRequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.TestRequestRandomnessFulfillment(&_BeaconVRFConsumer.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) TestRequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.TestRequestRandomnessFulfillment(&_BeaconVRFConsumer.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
- return _BeaconVRFConsumer.contract.Transact(opts, "transferOwnership", to)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.TransferOwnership(&_BeaconVRFConsumer.TransactOpts, to)
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _BeaconVRFConsumer.Contract.TransferOwnership(&_BeaconVRFConsumer.TransactOpts, to)
-}
-
-type BeaconVRFConsumerCoordinatorUpdatedIterator struct {
- Event *BeaconVRFConsumerCoordinatorUpdated
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *BeaconVRFConsumerCoordinatorUpdatedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(BeaconVRFConsumerCoordinatorUpdated)
- 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(BeaconVRFConsumerCoordinatorUpdated)
- 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 *BeaconVRFConsumerCoordinatorUpdatedIterator) Error() error {
- return it.fail
-}
-
-func (it *BeaconVRFConsumerCoordinatorUpdatedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type BeaconVRFConsumerCoordinatorUpdated struct {
- Coordinator common.Address
- Raw types.Log
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) FilterCoordinatorUpdated(opts *bind.FilterOpts, coordinator []common.Address) (*BeaconVRFConsumerCoordinatorUpdatedIterator, error) {
-
- var coordinatorRule []interface{}
- for _, coordinatorItem := range coordinator {
- coordinatorRule = append(coordinatorRule, coordinatorItem)
- }
-
- logs, sub, err := _BeaconVRFConsumer.contract.FilterLogs(opts, "CoordinatorUpdated", coordinatorRule)
- if err != nil {
- return nil, err
- }
- return &BeaconVRFConsumerCoordinatorUpdatedIterator{contract: _BeaconVRFConsumer.contract, event: "CoordinatorUpdated", logs: logs, sub: sub}, nil
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) WatchCoordinatorUpdated(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerCoordinatorUpdated, coordinator []common.Address) (event.Subscription, error) {
-
- var coordinatorRule []interface{}
- for _, coordinatorItem := range coordinator {
- coordinatorRule = append(coordinatorRule, coordinatorItem)
- }
-
- logs, sub, err := _BeaconVRFConsumer.contract.WatchLogs(opts, "CoordinatorUpdated", coordinatorRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(BeaconVRFConsumerCoordinatorUpdated)
- if err := _BeaconVRFConsumer.contract.UnpackLog(event, "CoordinatorUpdated", 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 (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) ParseCoordinatorUpdated(log types.Log) (*BeaconVRFConsumerCoordinatorUpdated, error) {
- event := new(BeaconVRFConsumerCoordinatorUpdated)
- if err := _BeaconVRFConsumer.contract.UnpackLog(event, "CoordinatorUpdated", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type BeaconVRFConsumerOwnershipTransferRequestedIterator struct {
- Event *BeaconVRFConsumerOwnershipTransferRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *BeaconVRFConsumerOwnershipTransferRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(BeaconVRFConsumerOwnershipTransferRequested)
- 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(BeaconVRFConsumerOwnershipTransferRequested)
- 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 *BeaconVRFConsumerOwnershipTransferRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *BeaconVRFConsumerOwnershipTransferRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type BeaconVRFConsumerOwnershipTransferRequested struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BeaconVRFConsumerOwnershipTransferRequestedIterator, 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 := _BeaconVRFConsumer.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &BeaconVRFConsumerOwnershipTransferRequestedIterator{contract: _BeaconVRFConsumer.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerOwnershipTransferRequested, 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 := _BeaconVRFConsumer.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(BeaconVRFConsumerOwnershipTransferRequested)
- if err := _BeaconVRFConsumer.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 (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) ParseOwnershipTransferRequested(log types.Log) (*BeaconVRFConsumerOwnershipTransferRequested, error) {
- event := new(BeaconVRFConsumerOwnershipTransferRequested)
- if err := _BeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type BeaconVRFConsumerOwnershipTransferredIterator struct {
- Event *BeaconVRFConsumerOwnershipTransferred
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *BeaconVRFConsumerOwnershipTransferredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(BeaconVRFConsumerOwnershipTransferred)
- 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(BeaconVRFConsumerOwnershipTransferred)
- 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 *BeaconVRFConsumerOwnershipTransferredIterator) Error() error {
- return it.fail
-}
-
-func (it *BeaconVRFConsumerOwnershipTransferredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type BeaconVRFConsumerOwnershipTransferred struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BeaconVRFConsumerOwnershipTransferredIterator, 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 := _BeaconVRFConsumer.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &BeaconVRFConsumerOwnershipTransferredIterator{contract: _BeaconVRFConsumer.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerOwnershipTransferred, 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 := _BeaconVRFConsumer.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(BeaconVRFConsumerOwnershipTransferred)
- if err := _BeaconVRFConsumer.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 (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) ParseOwnershipTransferred(log types.Log) (*BeaconVRFConsumerOwnershipTransferred, error) {
- event := new(BeaconVRFConsumerOwnershipTransferred)
- if err := _BeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type SMyBeaconRequests struct {
- SlotNumber uint32
- ConfirmationDelay *big.Int
- NumWords uint16
- Requester common.Address
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumer) ParseLog(log types.Log) (generated.AbigenLog, error) {
- switch log.Topics[0] {
- case _BeaconVRFConsumer.abi.Events["CoordinatorUpdated"].ID:
- return _BeaconVRFConsumer.ParseCoordinatorUpdated(log)
- case _BeaconVRFConsumer.abi.Events["OwnershipTransferRequested"].ID:
- return _BeaconVRFConsumer.ParseOwnershipTransferRequested(log)
- case _BeaconVRFConsumer.abi.Events["OwnershipTransferred"].ID:
- return _BeaconVRFConsumer.ParseOwnershipTransferred(log)
-
- default:
- return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
- }
-}
-
-func (BeaconVRFConsumerCoordinatorUpdated) Topic() common.Hash {
- return common.HexToHash("0xc258faa9a17ddfdf4130b4acff63a289202e7d5f9e42f366add65368575486bc")
-}
-
-func (BeaconVRFConsumerOwnershipTransferRequested) Topic() common.Hash {
- return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
-}
-
-func (BeaconVRFConsumerOwnershipTransferred) Topic() common.Hash {
- return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
-}
-
-func (_BeaconVRFConsumer *BeaconVRFConsumer) Address() common.Address {
- return _BeaconVRFConsumer.address
-}
-
-type BeaconVRFConsumerInterface interface {
- Fail(opts *bind.CallOpts) (bool, error)
-
- IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error)
-
- Owner(opts *bind.CallOpts) (common.Address, error)
-
- SReceivedRandomnessByRequestID(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SArguments(opts *bind.CallOpts) ([]byte, error)
-
- SGasAvailable(opts *bind.CallOpts) (*big.Int, error)
-
- SMostRecentRequestID(opts *bind.CallOpts) (*big.Int, error)
-
- SMyBeaconRequests(opts *bind.CallOpts, arg0 *big.Int) (SMyBeaconRequests,
-
- error)
-
- SRandomWords(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- SRequestsIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- SSubId(opts *bind.CallOpts) (uint64, error)
-
- AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
-
- RawFulfillRandomWords(opts *bind.TransactOpts, requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error)
-
- SetCoordinator(opts *bind.TransactOpts, coordinator common.Address) (*types.Transaction, error)
-
- SetFail(opts *bind.TransactOpts, shouldFail bool) (*types.Transaction, error)
-
- StoreBeaconRequest(opts *bind.TransactOpts, reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error)
-
- TestRedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int) (*types.Transaction, error)
-
- TestRequestRandomness(opts *bind.TransactOpts, numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error)
-
- TestRequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error)
-
- TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
-
- FilterCoordinatorUpdated(opts *bind.FilterOpts, coordinator []common.Address) (*BeaconVRFConsumerCoordinatorUpdatedIterator, error)
-
- WatchCoordinatorUpdated(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerCoordinatorUpdated, coordinator []common.Address) (event.Subscription, error)
-
- ParseCoordinatorUpdated(log types.Log) (*BeaconVRFConsumerCoordinatorUpdated, error)
-
- FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BeaconVRFConsumerOwnershipTransferRequestedIterator, error)
-
- WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferRequested(log types.Log) (*BeaconVRFConsumerOwnershipTransferRequested, error)
-
- FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BeaconVRFConsumerOwnershipTransferredIterator, error)
-
- WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferred(log types.Log) (*BeaconVRFConsumerOwnershipTransferred, error)
-
- ParseLog(log types.Log) (generated.AbigenLog, error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/ocr2vrf/generated/vrf_coordinator/vrf_coordinator.go b/core/gethwrappers/ocr2vrf/generated/vrf_coordinator/vrf_coordinator.go
deleted file mode 100644
index f20d5494452..00000000000
--- a/core/gethwrappers/ocr2vrf/generated/vrf_coordinator/vrf_coordinator.go
+++ /dev/null
@@ -1,3870 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package vrf_coordinator
-
-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
-)
-
-type ECCArithmeticG1Point struct {
- P [2]*big.Int
-}
-
-type VRFBeaconTypesCallback struct {
- RequestID *big.Int
- NumWords uint16
- Requester common.Address
- Arguments []byte
- GasAllowance *big.Int
- SubID *big.Int
- GasPrice *big.Int
- WeiPerUnitLink *big.Int
-}
-
-type VRFBeaconTypesCoordinatorConfig struct {
- UseReasonableGasPrice bool
- ReentrancyLock bool
- Paused bool
- PremiumPercentage uint8
- UnusedGasPenaltyPercent uint8
- StalenessSeconds uint32
- RedeemableRequestGasOverhead uint32
- CallbackRequestGasOverhead uint32
- ReasonableGasPriceStalenessBlocks uint32
- FallbackWeiPerUnitLink *big.Int
-}
-
-type VRFBeaconTypesCostedCallback struct {
- Callback VRFBeaconTypesCallback
- Price *big.Int
-}
-
-type VRFBeaconTypesOutputServed struct {
- Height uint64
- ConfirmationDelay *big.Int
- ProofG1X *big.Int
- ProofG1Y *big.Int
-}
-
-type VRFBeaconTypesVRFOutput struct {
- BlockHeight uint64
- ConfirmationDelay *big.Int
- VrfOutput ECCArithmeticG1Point
- Callbacks []VRFBeaconTypesCostedCallback
- ShouldStore bool
-}
-
-type VRFCoordinatorCallbackConfig struct {
- MaxCallbackGasLimit uint32
- MaxCallbackArgumentsLength uint32
-}
-
-var VRFCoordinatorMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"beaconPeriodBlocksArg\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BeaconPeriodMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestHeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earliestAllowed\",\"type\":\"uint256\"}],\"name\":\"BlockTooRecent\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16[10]\",\"name\":\"confirmationDelays\",\"type\":\"uint16[10]\"},{\"internalType\":\"uint8\",\"name\":\"violatingIndex\",\"type\":\"uint8\"}],\"name\":\"ConfirmationDelaysNotIncreasing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ContractPaused\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasAllowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLeft\",\"type\":\"uint256\"}],\"name\":\"GasAllowanceExceedsGasLeft\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"reportHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"separatorHeight\",\"type\":\"uint64\"}],\"name\":\"HistoryDomainSeparatorTooOld\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"actualBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredBalance\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"expectedLength\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCoordinatorConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidJuelsConversion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numRecipients\",\"type\":\"uint256\"}],\"name\":\"InvalidNumberOfRecipients\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestedSubID\",\"type\":\"uint256\"}],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestedVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"coordinatorVersion\",\"type\":\"uint8\"}],\"name\":\"MigrationVersionMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProducer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativePaymentGiven\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoWordsRequested\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16[10]\",\"name\":\"confDelays\",\"type\":\"uint16[10]\"}],\"name\":\"NonZeroDelayAfterZeroDelay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnMigrationNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"producer\",\"type\":\"address\"}],\"name\":\"ProducerAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestHeight\",\"type\":\"uint256\"}],\"name\":\"RandomnessNotAvailable\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestHeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"confDelay\",\"type\":\"uint256\"}],\"name\":\"RandomnessSeedNotFoundForCallbacks\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numRecipients\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numPayments\",\"type\":\"uint256\"}],\"name\":\"RecipientsPaymentsMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"expected\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"actual\",\"type\":\"address\"}],\"name\":\"ResponseMustBeRetrievedByRequester\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyRequestsReplaceContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySlotsReplaceContract\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"}],\"name\":\"TooManyWords\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockHeight\",\"type\":\"uint256\"}],\"name\":\"UniverseHasEndedBangBangBang\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCallbackArgumentsLength\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinator.CallbackConfig\",\"name\":\"newConfig\",\"type\":\"tuple\"}],\"name\":\"CallbackConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"useReasonableGasPrice\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"unusedGasPenaltyPercent\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"redeemableRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"callbackRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"reasonableGasPriceStalenessBlocks\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structVRFBeaconTypes.CoordinatorConfig\",\"name\":\"coordinatorConfig\",\"type\":\"tuple\"}],\"name\":\"CoordinatorConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"newVersion\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"recentBlockHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint256\",\"name\":\"proofG1X\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofG1Y\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structVRFBeaconTypes.OutputServed[]\",\"name\":\"outputsServed\",\"type\":\"tuple[]\"}],\"name\":\"OutputsServed\",\"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\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"PauseFlagChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"requestIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"successfulFulfillment\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"truncatedErrorData\",\"type\":\"bytes[]\"},{\"indexed\":false,\"internalType\":\"uint96[]\",\"name\":\"subBalances\",\"type\":\"uint96[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"subIDs\",\"type\":\"uint256[]\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nextBeaconOutputHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAllowance\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weiPerUnitLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"costJuels\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSubBalance\",\"type\":\"uint256\"}],\"name\":\"RandomnessFulfillmentRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"}],\"name\":\"RandomnessRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nextBeaconOutputHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"costJuels\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSubBalance\",\"type\":\"uint256\"}],\"name\":\"RandomnessRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NUM_CONF_DELAYS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"paymentsInJuels\",\"type\":\"uint256[]\"}],\"name\":\"batchTransferLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"getCallbackMemo\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfirmationDelays\",\"outputs\":[{\"internalType\":\"uint24[8]\",\"name\":\"\",\"type\":\"uint24[8]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getFulfillmentFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"pendingFulfillments\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionLinkBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_beaconPeriodBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_link\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIVRFMigration\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"encodedRequest\",\"type\":\"bytes\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"p\",\"type\":\"uint256[2]\"}],\"internalType\":\"structECCArithmetic.G1Point\",\"name\":\"vrfOutput\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"gasAllowance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weiPerUnitLink\",\"type\":\"uint256\"}],\"internalType\":\"structVRFBeaconTypes.Callback\",\"name\":\"callback\",\"type\":\"tuple\"},{\"internalType\":\"uint96\",\"name\":\"price\",\"type\":\"uint96\"}],\"internalType\":\"structVRFBeaconTypes.CostedCallback[]\",\"name\":\"callbacks\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"shouldStore\",\"type\":\"bool\"}],\"internalType\":\"structVRFBeaconTypes.VRFOutput[]\",\"name\":\"vrfOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"}],\"name\":\"processVRFOutputs\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"containsNewOutputs\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"redeemRandomness\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"randomness\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"requestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"requestRandomnessFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_callbackConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCallbackArgumentsLength\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_coordinatorConfig\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"useReasonableGasPrice\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"unusedGasPenaltyPercent\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"redeemableRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"callbackRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"reasonableGasPriceStalenessBlocks\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_pendingRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"slotNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_producer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCallbackArgumentsLength\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinator.CallbackConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setCallbackConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint24[8]\",\"name\":\"confDelays\",\"type\":\"uint24[8]\"}],\"name\":\"setConfirmationDelays\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"useReasonableGasPrice\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"unusedGasPenaltyPercent\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"redeemableRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"callbackRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"reasonableGasPriceStalenessBlocks\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"uint96\"}],\"internalType\":\"structVRFBeaconTypes.CoordinatorConfig\",\"name\":\"coordinatorConfig\",\"type\":\"tuple\"}],\"name\":\"setCoordinatorConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPauseFlag\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"producer\",\"type\":\"address\"}],\"name\":\"setProducer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"juelsAmount\",\"type\":\"uint256\"}],\"name\":\"transferLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60c06040523480156200001157600080fd5b50604051620062f5380380620062f5833981016040819052620000349162000239565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf816200018e565b5050506001600160a01b03166080908152604080519182018152600080835260208301819052908201819052662386f26fc10000606090920191909152642386f26fc160b01b6006556004805463ffffffff60281b191668ffffffff00000000001790558290036200014457604051632abc297960e01b815260040160405180910390fd5b60a0829052600e805465ffffffffffff16906000620001638362000278565b91906101000a81548165ffffffffffff021916908365ffffffffffff160217905550505050620002ac565b336001600160a01b03821603620001e85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080604083850312156200024d57600080fd5b825160208401519092506001600160a01b03811681146200026d57600080fd5b809150509250929050565b600065ffffffffffff808316818103620002a257634e487b7160e01b600052601160045260246000fd5b6001019392505050565b60805160a051615fdd620003186000396000818161075f01528181611ca301528181613cb301528181613ce201528181613d1a015261430e01526000818161047501528181610bb501528181611a410152818161237b01528181612d610152612df60152615fdd6000f3fe6080604052600436106101d65760003560e01c806304104edb146101db5780630ae09540146101fd57806316f6ee9a1461021d578063294daa491461025d5780632b38bafc1461027f5780632f7527cc1461029f5780633e79167f146102b457806340d6bb82146102d457806347c3e2cb146102ea5780634ffac83a14610385578063597d2f3c146103985780635d06b4ab146103b657806364d51a2a146103d657806373433a2f146103fe57806376f2e3f41461041e57806379ba50971461044e5780637d253aff1461046357806385c64e11146104a45780638c7cba66146104c65780638da5cb5b146104e65780638da92e71146105045780638eef585f146105245780639e20103614610544578063a21a23e414610564578063a4c0ed3614610579578063acfc6cdd14610599578063b2a7cac5146105c6578063b79fa6f7146105e6578063bd58017f146106cd578063bec4c08c146106ed578063c3fbb6fd1461070d578063cb6317971461072d578063cd0593df1461074d578063ce3f471914610781578063dac83d29146107a1578063db972c8b146107c1578063dc311dd3146107d4578063e30afa4a14610804578063f2fde38b14610849578063f99b1d6814610869578063f9c45ced14610889575b600080fd5b3480156101e757600080fd5b506101fb6101f6366004614abd565b6108a9565b005b34801561020957600080fd5b506101fb610218366004614ae1565b610a5e565b34801561022957600080fd5b5061024a610238366004614b11565b6000908152600c602052604090205490565b6040519081526020015b60405180910390f35b34801561026957600080fd5b5060015b60405160ff9091168152602001610254565b34801561028b57600080fd5b506101fb61029a366004614abd565b610cc0565b3480156102ab57600080fd5b5061026d600881565b3480156102c057600080fd5b506101fb6102cf366004614b2a565b610d21565b3480156102e057600080fd5b5061024a6103e881565b3480156102f657600080fd5b50610348610305366004614b11565b60106020526000908152604090205463ffffffff811690600160201b810462ffffff1690600160381b810461ffff1690600160481b90046001600160a01b031684565b6040805163ffffffff909516855262ffffff909316602085015261ffff909116918301919091526001600160a01b03166060820152608001610254565b61024a610393366004614cac565b610dd2565b3480156103a457600080fd5b506002546001600160601b031661024a565b3480156103c257600080fd5b506101fb6103d1366004614abd565b610f7e565b3480156103e257600080fd5b506103eb606481565b60405161ffff9091168152602001610254565b34801561040a57600080fd5b506101fb610419366004614d57565b61102a565b34801561042a57600080fd5b5061043e610439366004614dd9565b611115565b6040519015158152602001610254565b34801561045a57600080fd5b506101fb611453565b34801561046f57600080fd5b506104977f000000000000000000000000000000000000000000000000000000000000000081565b6040516102549190614e5b565b3480156104b057600080fd5b506104b96114fd565b6040516102549190614e6f565b3480156104d257600080fd5b506101fb6104e1366004614ec3565b611562565b3480156104f257600080fd5b506000546001600160a01b0316610497565b34801561051057600080fd5b506101fb61051f366004614f1d565b6115d6565b34801561053057600080fd5b506101fb61053f366004614f3a565b611640565b34801561055057600080fd5b5061024a61055f366004614f65565b61167c565b34801561057057600080fd5b5061024a61179d565b34801561058557600080fd5b506101fb610594366004615019565b6119e3565b3480156105a557600080fd5b506105b96105b4366004615068565b611bce565b60405161025491906150f2565b3480156105d257600080fd5b506101fb6105e1366004614b11565b611dd2565b3480156105f257600080fd5b506004546005546106629160ff80821692610100830482169262010000810483169263010000008204811692600160201b83049091169163ffffffff600160281b8204811692600160481b8304821692600160681b8104831692600160881b90910416906001600160601b03168a565b604080519a15158b5298151560208b01529615159789019790975260ff948516606089015292909316608087015263ffffffff90811660a087015291821660c0860152811660e08501529091166101008301526001600160601b031661012082015261014001610254565b3480156106d957600080fd5b50600a54610497906001600160a01b031681565b3480156106f957600080fd5b506101fb610708366004614ae1565b611f03565b34801561071957600080fd5b506101fb610728366004615105565b6120bf565b34801561073957600080fd5b506101fb610748366004614ae1565b6125ac565b34801561075957600080fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561078d57600080fd5b506101fb61079c366004615159565b612899565b3480156107ad57600080fd5b506101fb6107bc366004614ae1565b6128b2565b61024a6107cf36600461519a565b6129c3565b3480156107e057600080fd5b506107f46107ef366004614b11565b612c21565b6040516102549493929190615272565b34801561081057600080fd5b50600b5461082c9063ffffffff80821691600160201b90041682565b6040805163ffffffff938416815292909116602083015201610254565b34801561085557600080fd5b506101fb610864366004614abd565b612d0e565b34801561087557600080fd5b506101fb6108843660046152be565b612d1f565b34801561089557600080fd5b5061024a6108a43660046152ea565b612e88565b6108b1612f9f565b60095460005b81811015610a3657826001600160a01b0316600982815481106108dc576108dc615330565b6000918252602090912001546001600160a01b031603610a2457600961090360018461535c565b8154811061091357610913615330565b600091825260209091200154600980546001600160a01b03909216918390811061093f5761093f615330565b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905582600961097660018561535c565b8154811061098657610986615330565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060098054806109c5576109c561536f565b600082815260209020810160001990810180546001600160a01b03191690550190556040517ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af3790610a17908590614e5b565b60405180910390a1505050565b80610a2e81615385565b9150506108b7565b5081604051635428d44960e01b8152600401610a529190614e5b565b60405180910390fd5b50565b60008281526007602052604090205482906001600160a01b031680610a995760405163c5171ee960e01b815260048101839052602401610a52565b336001600160a01b03821614610ac45780604051636c51fda960e11b8152600401610a529190614e5b565b600454610100900460ff1615610aed5760405163769dd35360e11b815260040160405180910390fd5b600084815260086020526040902054600160601b90046001600160401b031615610b2a57604051631685ecdd60e31b815260040160405180910390fd5b6000848152600860209081526040918290208251808401909352546001600160601b038116808452600160601b9091046001600160401b031691830191909152610b7386612ff4565b600280546001600160601b03169082906000610b8f838561539e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb87846001600160601b03166040518363ffffffff1660e01b8152600401610c0a9291906153c5565b6020604051808303816000875af1158015610c29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4d91906153de565b610c7d5760405163cf47918160e01b81526001600160601b03808316600483015283166024820152604401610a52565b867f3784f77e8e883de95b5d47cd713ced01229fa74d118c0a462224bcb0516d43f18784604051610caf9291906153fb565b60405180910390a250505050505050565b610cc8612f9f565b600a546001600160a01b031615610cff57600a5460405163ea6d390560e01b8152610a52916001600160a01b031690600401614e5b565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b610d29612f9f565b6064610d3b60a0830160808401615437565b60ff161180610d555750610d556040820160208301614f1d565b80610d6b5750610d6b6060820160408301614f1d565b15610d895760405163b0e7bd8360e01b815260040160405180910390fd5b806004610d96828261549d565b9050507e28d3a46e95e67def989d41c66eb331add9809460b95b5fb4eb006157728fc581604051610dc79190615670565b60405180910390a150565b60045460009062010000900460ff1615610dff5760405163ab35696f60e01b815260040160405180910390fd5b600454610100900460ff1615610e285760405163769dd35360e11b815260040160405180910390fd5b3415610e4957604051630b829bad60e21b8152346004820152602401610a52565b6000806000610e5a88338989613143565b925092509250600080610e6d338b61328e565b600087815260106020908152604091829020885181548a8401518b8601516060808e015163ffffffff90951666ffffffffffffff1990941693909317600160201b62ffffff9384160217600160381b600160e81b031916600160381b61ffff92831602600160481b600160e81b03191617600160481b6001600160a01b03909516949094029390931790935584513381526001600160401b038b1694810194909452918e169383019390935281018e9052908c16608082015260a081018390526001600160601b03821660c0820152919350915085907fb7933fba96b6b452eb44f99fdc08052a45dff82363d59abaff0456931c3d24599060e00160405180910390a2509298975050505050505050565b610f86612f9f565b610f8f8161346a565b15610faf578060405163ac8a27ef60e01b8152600401610a529190614e5b565b600980546001810182556000919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af0162590610dc7908390614e5b565b600a546001600160a01b0316331461105557604051634bea32db60e11b815260040160405180910390fd5b828015806110635750601f81115b1561108457604051634ecc4fef60e01b815260048101829052602401610a52565b8082146110a85760405163339f8a9d60e01b8152610a529082908490600401615758565b60005b8181101561110d576110fb8686838181106110c8576110c8615330565b90506020020160208101906110dd9190614abd565b8585848181106110ef576110ef615330565b90506020020135612d1f565b8061110581615385565b9150506110ab565b505050505050565b600a546000906001600160a01b0316331461114357604051634bea32db60e11b815260040160405180910390fd5b60045462010000900460ff161561116d5760405163ab35696f60e01b815260040160405180910390fd5b6001600160c01b038416156111aa57600680546001600160601b038616600160a01b02600160201b600160a01b0390911663ffffffff4216171790555b6001600160401b038316156111ff5760068054436001600160401b03908116600160201b02600160201b600160601b0319918716600160601b0291909116600160201b600160a01b0319909216919091171790555b600080866001600160401b0381111561121a5761121a614b68565b60405190808252806020026020018201604052801561125357816020015b6112406148f6565b8152602001906001900390816112385790505b50905060005b8781101561135557600089898381811061127557611275615330565b90506020028101906112879190615766565b611290906158ea565b9050600061129f82888b6134d3565b905085806112aa5750805b604083015151519096501515806112c957506040820151516020015115155b15611340576040805160808101825283516001600160401b0316815260208085015162ffffff168183015284830180515151938301939093529151519091015160608201528451859061ffff881690811061132657611326615330565b6020026020010181905250848061133c906159d0565b9550505b5050808061134d90615385565b915050611259565b5060008261ffff166001600160401b0381111561137457611374614b68565b6040519080825280602002602001820160405280156113ad57816020015b61139a6148f6565b8152602001906001900390816113925790505b50905060005b8361ffff16811015611409578281815181106113d1576113d1615330565b60200260200101518282815181106113eb576113eb615330565b6020026020010181905250808061140190615385565b9150506113b3565b507ff10ea936d00579b4c52035ee33bf46929646b3aa87554c565d8fb2c7aa549c448588888460405161143f94939291906159f1565b60405180910390a150505095945050505050565b6001546001600160a01b031633146114a65760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610a52565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61150561492c565b6040805161010081019182905290600f90600890826000855b82829054906101000a900462ffffff1662ffffff168152602001906003019060208260020104928301926001038202915080841161151e5790505050505050905090565b61156a612f9f565b8051600b80546020808501805163ffffffff908116600160201b026001600160401b031990941695811695861793909317909355604080519485529251909116908301527f0cc54509a45ab33cd67614d4a2892c083ecf8fb43b9d29f6ea8130b9023e51df9101610dc7565b6115de612f9f565b60045460ff6201000090910416151581151514610a5b5760048054821515620100000262ff0000199091161790556040517f49ba7c1de2d8853088b6270e43df2118516b217f38b917dd2b80dea360860fbe90610dc790831515815260200190565b600a546001600160a01b0316331461166b57604051634bea32db60e11b815260040160405180910390fd5b611678600f82600861494b565b5050565b604080516101408101825260045460ff80821615158352610100808304821615156020808601919091526201000084048316151585870152630100000084048316606080870191909152600160201b808604909416608080880191909152600160281b860463ffffffff90811660a0890152600160481b8704811660c0890152600160681b8704811660e0890152600160881b9096048616938701939093526005546001600160601b039081166101208801528751938401885260065480871685526001600160401b03958104861693850193909352600160601b830490941696830196909652600160a01b90049091169381019390935260009283926117889288169187919061366b565b50506001600160601b03169695505050505050565b600454600090610100900460ff16156117c95760405163769dd35360e11b815260040160405180910390fd5b60045462010000900460ff16156117f35760405163ab35696f60e01b815260040160405180910390fd5b60003361180160014361535c565b6001546040516001600160601b0319606094851b81166020830152924060348201523090931b90911660548301526001600160c01b0319600160a01b90910460c01b16606882015260700160408051808303601f19018152919052805160209091012060018054919250600160a01b9091046001600160401b031690601461188883615a86565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b038111156118c7576118c7614b68565b6040519080825280602002602001820160405280156118f0578160200160208202803683370190505b5060408051808201825260008082526020808301828152878352600882528483209351845491516001600160601b039091166001600160a01b031992831617600160601b6001600160401b039092169190910217909355835160608101855233815280820183815281860187815289855260078452959093208151815486166001600160a01b03918216178255935160018201805490961694169390931790935592518051949550919390926119ad9260028501929101906149e9565b505060405133915083907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d90600090a350905090565b600454610100900460ff1615611a0c5760405163769dd35360e11b815260040160405180910390fd5b60045462010000900460ff1615611a365760405163ab35696f60e01b815260040160405180910390fd5b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a7f576040516344b0e3c360e01b815260040160405180910390fd5b60208114611aa557604051636865567560e01b8152610a52906020908390600401615aaa565b6000611ab382840184614b11565b6000818152600760205260409020549091506001600160a01b0316611aee5760405163c5171ee960e01b815260048101829052602401610a52565b600081815260086020526040812080546001600160601b031691869190611b158385615abe565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600260008282829054906101000a90046001600160601b0316611b5d9190615abe565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a828784611bb09190615ade565b604051611bbe929190615758565b60405180910390a2505050505050565b600454606090610100900460ff1615611bfa5760405163769dd35360e11b815260040160405180910390fd5b60008381526010602081815260408084208151608081018352815463ffffffff8116825262ffffff600160201b8204168286015261ffff600160381b820416938201939093526001600160a01b03600160481b8404811660608301908152968a9052949093526001600160e81b031990911690559151163314611c9857806060015133604051638e30e82360e01b8152600401610a52929190615af1565b8051600090611cce907f00000000000000000000000000000000000000000000000000000000000000009063ffffffff16615b0b565b90506000611cda613715565b90506000836020015162ffffff1682611cf3919061535c565b9050808310611d385782846020015162ffffff1684611d129190615ade565b611d1d906001615ade565b6040516315ad27c360e01b8152600401610a52929190615758565b6001600160401b03831115611d63576040516302c6ef8160e11b815260048101849052602401610a52565b604051888152339088907f16f3f633197fafab10a5df69e6f3f2f7f20092f08d8d47de0a91c0f4b96a1a259060200160405180910390a3611dc68785600d6000611db1888a6020015161379f565b815260200190815260200160002054866137ae565b98975050505050505050565b600454610100900460ff1615611dfb5760405163769dd35360e11b815260040160405180910390fd5b6000818152600760205260409020546001600160a01b0316611e335760405163c5171ee960e01b815260048101829052602401610a52565b6000818152600760205260409020600101546001600160a01b03163314611e8a576000818152600760205260409081902060010154905163d084e97560e01b8152610a52916001600160a01b031690600401614e5b565b6000818152600760205260409081902080546001600160a01b031980821633908117845560019093018054909116905591516001600160a01b039092169183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611ef7918591615af1565b60405180910390a25050565b60008281526007602052604090205482906001600160a01b031680611f3e5760405163c5171ee960e01b815260048101839052602401610a52565b336001600160a01b03821614611f695780604051636c51fda960e11b8152600401610a529190614e5b565b600454610100900460ff1615611f925760405163769dd35360e11b815260040160405180910390fd5b60045462010000900460ff1615611fbc5760405163ab35696f60e01b815260040160405180910390fd5b60008481526007602052604090206002015460631901611fef576040516305a48e0f60e01b815260040160405180910390fd5b60036000611ffd8587613967565b815260208101919091526040016000205460ff166120b9576001600360006120258688613967565b815260208082019290925260409081016000908120805460ff191694151594909417909355868352600782528083206002018054600181018255908452919092200180546001600160a01b0319166001600160a01b0386161790555184907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1906120b0908690614e5b565b60405180910390a25b50505050565b600454610100900460ff16156120e85760405163769dd35360e11b815260040160405180910390fd5b6120f18361346a565b6121105782604051635428d44960e01b8152600401610a529190614e5b565b604081146121355760408051636865567560e01b8152610a5291908390600401615aaa565b600061214382840184615b22565b90506000806000806121588560200151612c21565b9350935093509350816001600160a01b0316336001600160a01b0316146121945781604051636c51fda960e11b8152600401610a529190614e5b565b876001600160a01b031663294daa496040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f69190615b5c565b60ff16856000015160ff1614612293578460000151886001600160a01b031663294daa496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226d9190615b5c565b60405163e7aada9560e01b815260ff928316600482015291166024820152604401610a52565b6001600160401b038316156122bb57604051631685ecdd60e31b815260040160405180910390fd5b60006040518060a001604052806122d0600190565b60ff16815260200187602001518152602001846001600160a01b03168152602001838152602001866001600160601b031681525090506000816040516020016123199190615b79565b60405160208183030381529060405290506123378760200151612ff4565b600280548791906000906123559084906001600160601b031661539e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8b886040518363ffffffff1660e01b81526004016123c79291906153fb565b6020604051808303816000875af11580156123e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240a91906153de565b61244b5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a52565b60405163ce3f471960e01b81526001600160a01b038b169063ce3f471990612477908490600401615c25565b600060405180830381600087803b15801561249157600080fd5b505af11580156124a5573d6000803e3d6000fd5b50506004805461ff00191661010017905550600090505b835181101561254f578381815181106124d7576124d7615330565b60200260200101516001600160a01b0316638ea981178c6040518263ffffffff1660e01b815260040161250a9190614e5b565b600060405180830381600087803b15801561252457600080fd5b505af1158015612538573d6000803e3d6000fd5b50505050808061254790615385565b9150506124bc565b506004805461ff00191690556020870151875160405160ff909116907fbd89b747474d3fc04664dfbd1d56ae7ffbe46ee097cdb9979c13916bb76269ce90612598908e90614e5b565b60405180910390a350505050505050505050565b60008281526007602052604090205482906001600160a01b0316806125e75760405163c5171ee960e01b815260048101839052602401610a52565b336001600160a01b038216146126125780604051636c51fda960e11b8152600401610a529190614e5b565b600454610100900460ff161561263b5760405163769dd35360e11b815260040160405180910390fd5b600084815260086020526040902054600160601b90046001600160401b03161561267857604051631685ecdd60e31b815260040160405180910390fd5b600360006126868587613967565b815260208101919091526040016000205460ff166126bb5783836040516379bfd40160e01b8152600401610a52929190615c38565b60008481526007602090815260408083206002018054825181850281018501909352808352919290919083018282801561271e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612700575b50505050509050600060018251612735919061535c565b905060005b825181101561284057856001600160a01b031683828151811061275f5761275f615330565b60200260200101516001600160a01b03160361282e57600083838151811061278957612789615330565b6020026020010151905080600760008a815260200190815260200160002060020183815481106127bb576127bb615330565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558981526007909152604090206002018054806128065761280661536f565b600082815260209020810160001990810180546001600160a01b031916905501905550612840565b8061283881615385565b91505061273a565b506003600061284f8789613967565b815260208101919091526040908101600020805460ff191690555186907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a790611bbe908890614e5b565b604051632cb6686f60e01b815260040160405180910390fd5b60008281526007602052604090205482906001600160a01b0316806128ed5760405163c5171ee960e01b815260048101839052602401610a52565b336001600160a01b038216146129185780604051636c51fda960e11b8152600401610a529190614e5b565b600454610100900460ff16156129415760405163769dd35360e11b815260040160405180910390fd5b6000848152600760205260409020600101546001600160a01b038481169116146120b9576000848152600760205260409081902060010180546001600160a01b0319166001600160a01b0386161790555184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1906120b09033908790615af1565b60045460009062010000900460ff16156129f05760405163ab35696f60e01b815260040160405180910390fd5b600454610100900460ff1615612a195760405163769dd35360e11b815260040160405180910390fd5b3415612a3a57604051630b829bad60e21b8152346004820152602401610a52565b600080612a4989338a8a613143565b925050915060006040518061010001604052808481526020018a61ffff168152602001336001600160a01b031681526020018781526020018863ffffffff166001600160601b031681526020018b81526020016000815260200160008152509050600080612ab68361397d565b60c087019190915260e08601919091526040519193509150612ae29085908c908f908790602001615c4f565b60405160208183030381529060405280519060200120600c6000878152602001908152602001600020819055506000604051806101600160405280878152602001336001600160a01b03168152602001866001600160401b031681526020018c62ffffff1681526020018e81526020018d61ffff1681526020018b63ffffffff1681526020018581526020018a8152602001848152602001836001600160601b0316815250905080600001517f01872fb9c7d6d68af06a17347935e04412da302a377224c205e672c26e18c37f82602001518360400151846060015185608001518660a001518760c001518860e0015160c001518960e0015160e001518a61010001518b61012001518c6101400151604051612c089b9a99989796959493929190615d02565b60405180910390a250939b9a5050505050505050505050565b600081815260076020526040812054819081906060906001600160a01b0316612c605760405163c5171ee960e01b815260048101869052602401610a52565b60008581526008602090815260408083205460078352928190208054600290910180548351818602810186019094528084526001600160601b03861695600160601b90046001600160401b0316946001600160a01b03909316939192839190830182828015612cf857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612cda575b5050505050905093509350935093509193509193565b612d16612f9f565b610a5b81613bb4565b600a546001600160a01b03163314612d4a57604051634bea32db60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90612d9890859085906004016153c5565b6020604051808303816000875af1158015612db7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ddb91906153de565b611678576040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190612e2b903090600401614e5b565b602060405180830381865afa158015612e48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e6c9190615d98565b8160405163cf47918160e01b8152600401610a52929190615758565b604080516101408101825260045460ff80821615158352610100808304821615156020808601919091526201000084048316151585870152630100000084048316606080870191909152600160201b80860490941660808088019190915263ffffffff600160281b8704811660a0890152600160481b8704811660c0890152600160681b8704811660e0890152600160881b9096048616938701939093526005546001600160601b039081166101208801528751938401885260065495861684526001600160401b03948604851692840192909252600160601b850490931695820195909552600160a01b90920490931692810192909252600091612f8d9190613c57565b6001600160601b031690505b92915050565b6000546001600160a01b03163314612ff25760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610a52565b565b6000818152600760209081526040808320815160608101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181529295939486019383018282801561307a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161305c575b505050505081525050905060005b8160400151518110156130ea57600360006130c0846040015184815181106130b2576130b2615330565b602002602001015186613967565b81526020810191909152604001600020805460ff19169055806130e281615385565b915050613088565b50600082815260076020526040812080546001600160a01b031990811682556001820180549091169055906131226002830182614a3e565b505050600090815260086020526040902080546001600160a01b0319169055565b600061314d614a5c565b60006103e88561ffff16111561317c57846103e8604051634a90778560e01b8152600401610a52929190615aaa565b8461ffff166000036131a1576040516308fad2a760e01b815260040160405180910390fd5b6000806131ac613c9d565b600e54919350915065ffffffffffff1660006132178b8b84604080513060208201529081018490526001600160a01b038316606082015265ffffffffffff8216608082015260009060a00160408051601f198184030181529190528051602090910120949350505050565b9050613224826001615db1565b600e805465ffffffffffff9290921665ffffffffffff199092169190911790556040805160808101825263ffffffff909416845262ffffff8916602085015261ffff8a16908401526001600160a01b038a1660608401529550909350909150509450945094915050565b604080516080808201835260065463ffffffff8082168452600160201b8083046001600160401b03908116602080880191909152600160601b850490911686880152600160a01b9093046001600160601b0390811660608088019190915287516101408101895260045460ff808216151583526101008083048216151598840198909852620100008204811615159a83019a909a52630100000081048a169282019290925292810490971694820194909452600160281b8604821660a0820152600160481b8604821660c0820152600160681b8604821660e0820152600160881b9095041690840152600554166101208301526000918291906003836133948888613967565b815260208101919091526040016000205460ff166133c95784866040516379bfd40160e01b8152600401610a52929190615c38565b60006133d58284613c57565b600087815260086020526040902080546001600160601b0392831693509091168281101561342457815460405163cf47918160e01b8152610a52916001600160601b0316908590600401615dd0565b81546001600160601b0319908116918490036001600160601b038181169390931790935560028054918216918316859003909216179055909450925050505b9250929050565b6000805b6009548110156134ca57826001600160a01b03166009828154811061349557613495615330565b6000918252602090912001546001600160a01b0316036134b85750600192915050565b806134c281615385565b91505061346e565b50600092915050565b6000826001600160401b031684600001516001600160401b0316111561352257835160405163012d824d60e01b81526001600160401b0380861660048301529091166024820152604401610a52565b606084015151604080860151905160009161353f91602001615de9565b60405160208183030381529060405280519060200120905085604001516000015160006002811061357257613572615330565b602002015115801561358b575060408601515160200151155b156135c557600d60006135af88600001516001600160401b0316896020015161379f565b8152602001908152602001600020549050613648565b856080015115613648576000600d60006135f089600001516001600160401b03168a6020015161379f565b81526020810191909152604001600020549050806136425781600d60006136288a600001516001600160401b03168b6020015161379f565b815260208101919091526040016000205560019350613646565b8091505b505b6000613655838389613d70565b905083806136605750805b979650505050505050565b60008060008061367b8686614189565b6001600160401b031690506000613693826010615b0b565b9050600060146136a4836015615b0b565b6136ae9190615e29565b89516136ba9190615b0b565b838960e0015163ffffffff168c6136d19190615abe565b6001600160601b03166136e49190615b0b565b6136ee9190615ade565b90506000806137008360008c8c614202565b909d909c50949a509398505050505050505050565b60004661a4b181148061372a575062066eed81145b156137985760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561376e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137929190615d98565b91505090565b4391505090565b62ffffff1660189190911b1790565b6060826137e05760405163220a34e960e11b8152600481018690526001600160401b0383166024820152604401610a52565b604080516020808201889052865163ffffffff168284015286015162ffffff166060808301919091529186015161ffff166080820152908501516001600160a01b031660a082015260c0810184905260009060e0016040516020818303038152906040528051906020012090506103e8856040015161ffff1611156138825784604001516103e8604051634a90778560e01b8152600401610a52929190615aaa565b6000856040015161ffff166001600160401b038111156138a4576138a4614b68565b6040519080825280602002602001820160405280156138cd578160200160208202803683370190505b50905060005b866040015161ffff168161ffff16101561395c57828160405160200161391092919091825260f01b6001600160f01b031916602082015260220190565b6040516020818303038152906040528051906020012060001c828261ffff168151811061393f5761393f615330565b602090810291909101015280613954816159d0565b9150506138d3565b509695505050505050565b60a081901b6001600160a01b0383161792915050565b6000806000806003600061399987604001518860a00151613967565b815260208101919091526040016000205460ff166139d6578460a0015185604001516040516379bfd40160e01b8152600401610a52929190615c38565b604080516080808201835260065463ffffffff80821684526001600160401b03600160201b8084048216602080880191909152600160601b8504909216868801526001600160601b03600160a01b909404841660608088019190915287516101408101895260045460ff808216151583526101008083048216151596840196909652620100008204811615159a83019a909a52630100000081048a168284015292830490981688870152600160281b8204841660a0890152600160481b8204841660c0890152600160681b8204841660e0890152600160881b90910490921690860152600554909116610120850152908801519088015191929160009182918291613ae291868861366b565b60a08d0151600090815260086020526040902080546001600160601b0394851697509295509093509116841115613b3a57805460405163cf47918160e01b8152610a52916001600160601b0316908690600401615dd0565b80546001600160601b0360016001600160401b03600160601b8085048216929092011602818116828416178790038083166001600160601b03199283166001600160a01b03199095169490941793909317909355600280548083168890039092169190931617909155929a91995097509095509350505050565b336001600160a01b03821603613c065760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610a52565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080613c648484614189565b8460c0015163ffffffff16613c799190615e3d565b6001600160401b031690506000613c938260008787614202565b5095945050505050565b6000806000613caa613715565b90506000613cd87f000000000000000000000000000000000000000000000000000000000000000083615e60565b9050600081613d077f000000000000000000000000000000000000000000000000000000000000000085615ade565b613d11919061535c565b90506000613d3f7f000000000000000000000000000000000000000000000000000000000000000083615e29565b905063ffffffff8110613d65576040516307b2a52360e41b815260040160405180910390fd5b909590945092505050565b6000806040518060c00160405280866001600160401b03811115613d9657613d96614b68565b604051908082528060200260200182016040528015613dbf578160200160208202803683370190505b508152602001866001600160401b03811115613ddd57613ddd614b68565b6040519080825280601f01601f191660200182016040528015613e07576020820181803683370190505b508152602001866001600160401b03811115613e2557613e25614b68565b604051908082528060200260200182016040528015613e5857816020015b6060815260200190600190039081613e435790505b50815260006020820152604001866001600160401b03811115613e7d57613e7d614b68565b604051908082528060200260200182016040528015613ea6578160200160208202803683370190505b508152602001866001600160401b03811115613ec457613ec4614b68565b604051908082528060200260200182016040528015613eed578160200160208202803683370190505b509052905060005b8581101561406c57600084606001518281518110613f1557613f15615330565b60200260200101519050600080600080613f3989600001518a602001518c8861424d565b93509350935093508315613f8d57828760400151886060015161ffff1681518110613f6657613f66615330565b602090810291909101015260608701805190613f81826159d0565b61ffff16905250613fc0565b600160f81b87602001518781518110613fa857613fa8615330565b60200101906001600160f81b031916908160001a9053505b8780613fca575080155b85515188518051929a50909188908110613fe657613fe6615330565b602002602001018181525050818760800151878151811061400957614009615330565b60200260200101906001600160601b031690816001600160601b031681525050846000015160a001518760a00151878151811061404857614048615330565b6020026020010181815250505050505050808061406490615385565b915050613ef5565b5060608301515115614181576000816060015161ffff166001600160401b0381111561409a5761409a614b68565b6040519080825280602002602001820160405280156140cd57816020015b60608152602001906001900390816140b85790505b50905060005b826060015161ffff1681101561413157826040015181815181106140f9576140f9615330565b602002602001015182828151811061411357614113615330565b6020026020010181905250808061412990615385565b9150506140d3565b5081516020830151608084015160a08501516040517f8f79f730779e875ce76c428039cc2052b5b5918c2a55c598fab251c1198aec549461417794909390928792615ead565b60405180910390a1505b509392505050565b815160009080156141a6575060408201516001600160401b031615155b156141fa5761010083015163ffffffff16431080806141e757506101008401516141d69063ffffffff164361535c565b83602001516001600160401b031610155b156141f85750506040810151612f99565b505b503a92915050565b600080600060648560600151606461421a9190615f50565b6142279060ff1689615b0b565b6142319190615e29565b905061423f818787876145bc565b925092505094509492505050565b805160a09081015160009081526008602090815260408083208551948501519151939460609486948594859261428b928e928e929091879101615c4f565b60408051601f19818403018152918152815160209283012084516000908152600c90935291205490915081146142fe5750505460408051808201909152601081526f756e6b6e6f776e2063616c6c6261636b60801b60208201526001955093506001600160601b031691508390506145b1565b50614307614a5c565b600061433c7f00000000000000000000000000000000000000000000000000000000000000006001600160401b038e16615e29565b6040805160808101825263ffffffff909216825262ffffff8d1660208084019190915285015161ffff16828201528401516001600160a01b0316606082015291508990506143d0575050604080518082019091526016815275756e617661696c61626c652072616e646f6d6e65737360501b60208201529054600195509093506001600160601b03169150600090506145b1565b60006143e28360000151838c8f6137ae565b606080840151855191860151604051939450909260009263d21ea8fd60e01b9261441192879190602401615f69565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526004805461ff00191661010017905590506000805a9050600061447c8e60000151608001516001600160601b0316896040015186614630565b9093509050806144b1578d516080015160405163aad1598360e01b8152610a52916001600160601b0316908490600401615758565b506000610bb85a6144c29190615ade565b6004805461ff00191690559050818110156144eb576144eb6144e4828461535c565b8f5161466f565b8854600160601b90046001600160401b031689600c61450983615f94565b82546001600160401b039182166101009390930a92830291909202199091161790555087516000908152600c60205260408120558261457f5760408051808201909152601081526f195e1958dd5d1a5bdb8819985a5b195960821b60208201528954600191906001600160601b0316600061459f565b604080516020810190915260008082528a549091906001600160601b0316825b9c509c509c509c505050505050505050505b945094509450949050565b6000808085156145cc57856145d6565b6145d6858561489b565b90506000816145ed89670de0b6b3a7640000615b0b565b6145f79190615e29565b9050676765c793fa10079d601b1b8111156146245760405162de437160e81b815260040160405180910390fd5b97909650945050505050565b6000805a610bb8811061466657610bb881039050856040820482031115614666576000808551602087016000898bf19250600191505b50935093915050565b80608001516001600160601b0316821115614688575050565b6004546000906064906146a590600160201b900460ff1682615fb7565b60ff168360c001518585608001516001600160601b03166146c6919061535c565b6146d09190615b0b565b6146da9190615b0b565b6146e49190615e29565b60e080840151604080516101408101825260045460ff80821615158352610100808304821615156020808601919091526201000084048316151585870152630100000084048316606080870191909152600160201b80860490941660808088019190915263ffffffff600160281b8704811660a0890152600160481b8704811660c0890152600160681b870481169a88019a909a52600160881b9095048916928601929092526005546001600160601b039081166101208701528651948501875260065498891685526001600160401b03938904841691850191909152600160601b880490921694830194909452600160a01b909504909416918401919091529293506000926147f792859291906145bc565b5060a08401516000908152600860205260408120805492935083929091906148299084906001600160601b0316615abe565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600260008282829054906101000a90046001600160601b03166148719190615abe565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050505050565b60a0820151606082015160009190600163ffffffff831611908180156148d7575084516148ce9063ffffffff164261535c565b8363ffffffff16105b156148e457506101208501515b6001600160601b031695945050505050565b604051806080016040528060006001600160401b03168152602001600062ffffff16815260200160008152602001600081525090565b6040518061010001604052806008906020820280368337509192915050565b6001830191839082156149d95791602002820160005b838211156149a857833562ffffff1683826101000a81548162ffffff021916908362ffffff1602179055509260200192600301602081600201049283019260010302614961565b80156149d75782816101000a81549062ffffff02191690556003016020816002010492830192600103026149a8565b505b506149e5929150614a83565b5090565b8280548282559060005260206000209081019282156149d9579160200282015b828111156149d957825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614a09565b5080546000825590600052602060002090810190610a5b9190614a83565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5b808211156149e55760008155600101614a84565b6001600160a01b0381168114610a5b57600080fd5b8035614ab881614a98565b919050565b600060208284031215614acf57600080fd5b8135614ada81614a98565b9392505050565b60008060408385031215614af457600080fd5b823591506020830135614b0681614a98565b809150509250929050565b600060208284031215614b2357600080fd5b5035919050565b60006101408284031215614b3d57600080fd5b50919050565b803561ffff81168114614ab857600080fd5b803562ffffff81168114614ab857600080fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715614ba057614ba0614b68565b60405290565b60405161010081016001600160401b0381118282101715614ba057614ba0614b68565b60405160a081016001600160401b0381118282101715614ba057614ba0614b68565b604051602081016001600160401b0381118282101715614ba057614ba0614b68565b604051601f8201601f191681016001600160401b0381118282101715614c3557614c35614b68565b604052919050565b600082601f830112614c4e57600080fd5b81356001600160401b03811115614c6757614c67614b68565b614c7a601f8201601f1916602001614c0d565b818152846020838601011115614c8f57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215614cc257600080fd5b84359350614cd260208601614b43565b9250614ce060408601614b55565b915060608501356001600160401b03811115614cfb57600080fd5b614d0787828801614c3d565b91505092959194509250565b60008083601f840112614d2557600080fd5b5081356001600160401b03811115614d3c57600080fd5b6020830191508360208260051b850101111561346357600080fd5b60008060008060408587031215614d6d57600080fd5b84356001600160401b0380821115614d8457600080fd5b614d9088838901614d13565b90965094506020870135915080821115614da957600080fd5b50614db687828801614d13565b95989497509550505050565b80356001600160401b0381168114614ab857600080fd5b600080600080600060808688031215614df157600080fd5b85356001600160401b03811115614e0757600080fd5b614e1388828901614d13565b90965094505060208601356001600160c01b0381168114614e3357600080fd5b9250614e4160408701614dc2565b9150614e4f60608701614dc2565b90509295509295909350565b6001600160a01b0391909116815260200190565b6101008101818360005b6008811015614e9d57815162ffffff16835260209283019290910190600101614e79565b50505092915050565b63ffffffff81168114610a5b57600080fd5b8035614ab881614ea6565b600060408284031215614ed557600080fd5b614edd614b7e565b8235614ee881614ea6565b81526020830135614ef881614ea6565b60208201529392505050565b8015158114610a5b57600080fd5b8035614ab881614f04565b600060208284031215614f2f57600080fd5b8135614ada81614f04565b6000610100808385031215614f4e57600080fd5b838184011115614f5d57600080fd5b509092915050565b60008060008060808587031215614f7b57600080fd5b843593506020850135614f8d81614ea6565b925060408501356001600160401b0380821115614fa957600080fd5b614fb588838901614c3d565b93506060870135915080821115614fcb57600080fd5b50614d0787828801614c3d565b60008083601f840112614fea57600080fd5b5081356001600160401b0381111561500157600080fd5b60208301915083602082850101111561346357600080fd5b6000806000806060858703121561502f57600080fd5b843561503a81614a98565b93506020850135925060408501356001600160401b0381111561505c57600080fd5b614db687828801614fd8565b60008060006060848603121561507d57600080fd5b833592506020840135915060408401356001600160401b038111156150a157600080fd5b6150ad86828701614c3d565b9150509250925092565b600081518084526020808501945080840160005b838110156150e7578151875295820195908201906001016150cb565b509495945050505050565b602081526000614ada60208301846150b7565b60008060006040848603121561511a57600080fd5b833561512581614a98565b925060208401356001600160401b0381111561514057600080fd5b61514c86828701614fd8565b9497909650939450505050565b6000806020838503121561516c57600080fd5b82356001600160401b0381111561518257600080fd5b61518e85828601614fd8565b90969095509350505050565b60008060008060008060c087890312156151b357600080fd5b863595506151c360208801614b43565b94506151d160408801614b55565b935060608701356151e181614ea6565b925060808701356001600160401b03808211156151fd57600080fd5b6152098a838b01614c3d565b935060a089013591508082111561521f57600080fd5b5061522c89828a01614c3d565b9150509295509295509295565b600081518084526020808501945080840160005b838110156150e75781516001600160a01b03168752958201959082019060010161524d565b6001600160601b03851681526001600160401b03841660208201526001600160a01b03831660408201526080606082018190526000906152b490830184615239565b9695505050505050565b600080604083850312156152d157600080fd5b82356152dc81614a98565b946020939093013593505050565b600080604083850312156152fd57600080fd5b8235915060208301356001600160401b0381111561531a57600080fd5b61532685828601614c3d565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115612f9957612f99615346565b634e487b7160e01b600052603160045260246000fd5b60006001820161539757615397615346565b5060010190565b6001600160601b038281168282160390808211156153be576153be615346565b5092915050565b6001600160a01b03929092168252602082015260400190565b6000602082840312156153f057600080fd5b8151614ada81614f04565b6001600160a01b039290921682526001600160601b0316602082015260400190565b60ff81168114610a5b57600080fd5b8035614ab88161541d565b60006020828403121561544957600080fd5b8135614ada8161541d565b60008135612f9981614f04565b60008135612f998161541d565b60008135612f9981614ea6565b6001600160601b0381168114610a5b57600080fd5b60008135612f998161547b565b81356154a881614f04565b815490151560ff1660ff19919091161781556154e36154c960208401615454565b82805461ff00191691151560081b61ff0016919091179055565b61550e6154f260408401615454565b82805462ff0000191691151560101b62ff000016919091179055565b61553761551d60608401615461565b825463ff000000191660189190911b63ff00000016178255565b61556461554660808401615461565b82805460ff60201b191660209290921b60ff60201b16919091179055565b61559761557360a0840161546e565b82805463ffffffff60281b191660289290921b63ffffffff60281b16919091179055565b6155ca6155a660c0840161546e565b82805463ffffffff60481b191660489290921b63ffffffff60481b16919091179055565b6155fd6155d960e0840161546e565b82805463ffffffff60681b191660689290921b63ffffffff60681b16919091179055565b61563161560d610100840161546e565b82805463ffffffff60881b191660889290921b63ffffffff60881b16919091179055565b6116786156416101208401615490565b6001830180546001600160601b0319166001600160601b0392909216919091179055565b8035614ab88161547b565b61014081016156888261568285614f12565b15159052565b61569460208401614f12565b151560208301526156a760408401614f12565b151560408301526156ba6060840161542c565b60ff1660608301526156ce6080840161542c565b60ff1660808301526156e260a08401614eb8565b63ffffffff1660a08301526156f960c08401614eb8565b63ffffffff1660c083015261571060e08401614eb8565b63ffffffff1660e0830152610100615729848201614eb8565b63ffffffff1690830152610120615741848201615665565b6001600160601b038116848301525b505092915050565b918252602082015260400190565b6000823560be1983360301811261577c57600080fd5b9190910192915050565b600082601f83011261579757600080fd5b813560206001600160401b03808311156157b3576157b3614b68565b8260051b6157c2838201614c0d565b93845285810183019383810190888611156157dc57600080fd5b84880192505b85831015611dc6578235848111156157f957600080fd5b8801601f196040828c038201121561581057600080fd5b615818614b7e565b878301358781111561582957600080fd5b8301610100818e038401121561583e57600080fd5b615846614ba6565b925088810135835261585a60408201614b43565b8984015261586a60608201614aad565b604084015260808101358881111561588157600080fd5b61588f8e8b83850101614c3d565b6060850152506158a160a08201615665565b608084015260c081013560a084015260e081013560c084015261010081013560e0840152508181526158d560408401615665565b818901528452505091840191908401906157e2565b600081360360c08112156158fd57600080fd5b615905614bc9565b61590e84614dc2565b8152602061591d818601614b55565b828201526040603f198401121561593357600080fd5b61593b614beb565b925036605f86011261594c57600080fd5b615954614b7e565b80608087013681111561596657600080fd5b604088015b81811015615982578035845292840192840161596b565b50908552604084019490945250509035906001600160401b038211156159a757600080fd5b6159b336838601615786565b60608201526159c460a08501614f12565b60808201529392505050565b600061ffff8083168181036159e7576159e7615346565b6001019392505050565b6000608080830160018060401b038089168552602060018060c01b038916818701526040828916818801526060858189015284895180875260a08a019150848b01965060005b81811015615a735787518051881684528681015162ffffff16878501528581015186850152840151848401529685019691880191600101615a37565b50909d9c50505050505050505050505050565b60006001600160401b038281166002600160401b031981016159e7576159e7615346565b61ffff929092168252602082015260400190565b6001600160601b038181168382160190808211156153be576153be615346565b80820180821115612f9957612f99615346565b6001600160a01b0392831681529116602082015260400190565b8082028115828204841417612f9957612f99615346565b600060408284031215615b3457600080fd5b615b3c614b7e565b8235615b478161541d565b81526020928301359281019290925250919050565b600060208284031215615b6e57600080fd5b8151614ada8161541d565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160a06080840152615bbe60c0840182615239565b608094909401516001600160601b031660a093909301929092525090919050565b6000815180845260005b81811015615c0557602081850181015186830182015201615be9565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000614ada6020830184615bdf565b9182526001600160a01b0316602082015260400190565b60018060401b038516815262ffffff84166020820152826040820152608060608201528151608082015261ffff60208301511660a082015260018060a01b0360408301511660c0820152600060608301516101008060e0850152615cb7610180850183615bdf565b91506080850151615cd2828601826001600160601b03169052565b505060a084015161012084015260c084015161014084015260e08401516101608401528091505095945050505050565b6001600160a01b038c1681526001600160401b038b16602082015262ffffff8a1660408201526060810189905261ffff8816608082015263ffffffff871660a082015260c0810186905260e081018590526101606101008201819052600090615d6d83820187615bdf565b61012084019590955250506001600160601b0391909116610140909101529998505050505050505050565b600060208284031215615daa57600080fd5b5051919050565b65ffffffffffff8181168382160190808211156153be576153be615346565b6001600160601b03929092168252602082015260400190565b815160408201908260005b6002811015614e9d578251825260209283019290910190600101615df4565b634e487b7160e01b600052601260045260246000fd5b600082615e3857615e38615e13565b500490565b6001600160401b0381811683821602808216919082811461575057615750615346565b600082615e6f57615e6f615e13565b500690565b600081518084526020808501945080840160005b838110156150e75781516001600160601b031687529582019590820190600101615e88565b60a081526000615ec060a08301886150b7565b602083820381850152615ed38289615bdf565b915083820360408501528187518084528284019150828160051b850101838a0160005b83811015615f2457601f19878403018552615f12838351615bdf565b94860194925090850190600101615ef6565b50508681036060880152615f38818a615e74565b9450505050508281036080840152611dc681856150b7565b60ff8181168382160190811115612f9957612f99615346565b838152606060208201526000615f8260608301856150b7565b82810360408401526152b48185615bdf565b60006001600160401b03821680615fad57615fad615346565b6000190192915050565b60ff8281168282160390811115612f9957612f9961534656fea164736f6c6343000813000a",
-}
-
-var VRFCoordinatorABI = VRFCoordinatorMetaData.ABI
-
-var VRFCoordinatorBin = VRFCoordinatorMetaData.Bin
-
-func DeployVRFCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, beaconPeriodBlocksArg *big.Int, linkToken common.Address) (common.Address, *types.Transaction, *VRFCoordinator, error) {
- parsed, err := VRFCoordinatorMetaData.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(VRFCoordinatorBin), backend, beaconPeriodBlocksArg, linkToken)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &VRFCoordinator{VRFCoordinatorCaller: VRFCoordinatorCaller{contract: contract}, VRFCoordinatorTransactor: VRFCoordinatorTransactor{contract: contract}, VRFCoordinatorFilterer: VRFCoordinatorFilterer{contract: contract}}, nil
-}
-
-type VRFCoordinator struct {
- address common.Address
- abi abi.ABI
- VRFCoordinatorCaller
- VRFCoordinatorTransactor
- VRFCoordinatorFilterer
-}
-
-type VRFCoordinatorCaller struct {
- contract *bind.BoundContract
-}
-
-type VRFCoordinatorTransactor struct {
- contract *bind.BoundContract
-}
-
-type VRFCoordinatorFilterer struct {
- contract *bind.BoundContract
-}
-
-type VRFCoordinatorSession struct {
- Contract *VRFCoordinator
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type VRFCoordinatorCallerSession struct {
- Contract *VRFCoordinatorCaller
- CallOpts bind.CallOpts
-}
-
-type VRFCoordinatorTransactorSession struct {
- Contract *VRFCoordinatorTransactor
- TransactOpts bind.TransactOpts
-}
-
-type VRFCoordinatorRaw struct {
- Contract *VRFCoordinator
-}
-
-type VRFCoordinatorCallerRaw struct {
- Contract *VRFCoordinatorCaller
-}
-
-type VRFCoordinatorTransactorRaw struct {
- Contract *VRFCoordinatorTransactor
-}
-
-func NewVRFCoordinator(address common.Address, backend bind.ContractBackend) (*VRFCoordinator, error) {
- abi, err := abi.JSON(strings.NewReader(VRFCoordinatorABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindVRFCoordinator(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinator{address: address, abi: abi, VRFCoordinatorCaller: VRFCoordinatorCaller{contract: contract}, VRFCoordinatorTransactor: VRFCoordinatorTransactor{contract: contract}, VRFCoordinatorFilterer: VRFCoordinatorFilterer{contract: contract}}, nil
-}
-
-func NewVRFCoordinatorCaller(address common.Address, caller bind.ContractCaller) (*VRFCoordinatorCaller, error) {
- contract, err := bindVRFCoordinator(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorCaller{contract: contract}, nil
-}
-
-func NewVRFCoordinatorTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFCoordinatorTransactor, error) {
- contract, err := bindVRFCoordinator(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorTransactor{contract: contract}, nil
-}
-
-func NewVRFCoordinatorFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFCoordinatorFilterer, error) {
- contract, err := bindVRFCoordinator(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorFilterer{contract: contract}, nil
-}
-
-func bindVRFCoordinator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := VRFCoordinatorMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _VRFCoordinator.Contract.VRFCoordinatorCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_VRFCoordinator *VRFCoordinatorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.VRFCoordinatorTransactor.contract.Transfer(opts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.VRFCoordinatorTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _VRFCoordinator.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.contract.Transfer(opts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "MAX_CONSUMERS")
-
- if err != nil {
- return *new(uint16), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) MAXCONSUMERS() (uint16, error) {
- return _VRFCoordinator.Contract.MAXCONSUMERS(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) MAXCONSUMERS() (uint16, error) {
- return _VRFCoordinator.Contract.MAXCONSUMERS(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) MAXNUMWORDS(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "MAX_NUM_WORDS")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) MAXNUMWORDS() (*big.Int, error) {
- return _VRFCoordinator.Contract.MAXNUMWORDS(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) MAXNUMWORDS() (*big.Int, error) {
- return _VRFCoordinator.Contract.MAXNUMWORDS(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) NUMCONFDELAYS(opts *bind.CallOpts) (uint8, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "NUM_CONF_DELAYS")
-
- if err != nil {
- return *new(uint8), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) NUMCONFDELAYS() (uint8, error) {
- return _VRFCoordinator.Contract.NUMCONFDELAYS(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) NUMCONFDELAYS() (uint8, error) {
- return _VRFCoordinator.Contract.NUMCONFDELAYS(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) GetCallbackMemo(opts *bind.CallOpts, requestId *big.Int) ([32]byte, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "getCallbackMemo", requestId)
-
- if err != nil {
- return *new([32]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) GetCallbackMemo(requestId *big.Int) ([32]byte, error) {
- return _VRFCoordinator.Contract.GetCallbackMemo(&_VRFCoordinator.CallOpts, requestId)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) GetCallbackMemo(requestId *big.Int) ([32]byte, error) {
- return _VRFCoordinator.Contract.GetCallbackMemo(&_VRFCoordinator.CallOpts, requestId)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) GetConfirmationDelays(opts *bind.CallOpts) ([8]*big.Int, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "getConfirmationDelays")
-
- if err != nil {
- return *new([8]*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new([8]*big.Int)).(*[8]*big.Int)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) GetConfirmationDelays() ([8]*big.Int, error) {
- return _VRFCoordinator.Contract.GetConfirmationDelays(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) GetConfirmationDelays() ([8]*big.Int, error) {
- return _VRFCoordinator.Contract.GetConfirmationDelays(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) GetFee(opts *bind.CallOpts, arg0 *big.Int, arg1 []byte) (*big.Int, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "getFee", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) GetFee(arg0 *big.Int, arg1 []byte) (*big.Int, error) {
- return _VRFCoordinator.Contract.GetFee(&_VRFCoordinator.CallOpts, arg0, arg1)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) GetFee(arg0 *big.Int, arg1 []byte) (*big.Int, error) {
- return _VRFCoordinator.Contract.GetFee(&_VRFCoordinator.CallOpts, arg0, arg1)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) GetFulfillmentFee(opts *bind.CallOpts, arg0 *big.Int, callbackGasLimit uint32, arguments []byte, arg3 []byte) (*big.Int, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "getFulfillmentFee", arg0, callbackGasLimit, arguments, arg3)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) GetFulfillmentFee(arg0 *big.Int, callbackGasLimit uint32, arguments []byte, arg3 []byte) (*big.Int, error) {
- return _VRFCoordinator.Contract.GetFulfillmentFee(&_VRFCoordinator.CallOpts, arg0, callbackGasLimit, arguments, arg3)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) GetFulfillmentFee(arg0 *big.Int, callbackGasLimit uint32, arguments []byte, arg3 []byte) (*big.Int, error) {
- return _VRFCoordinator.Contract.GetFulfillmentFee(&_VRFCoordinator.CallOpts, arg0, callbackGasLimit, arguments, arg3)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription,
-
- error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "getSubscription", subId)
-
- outstruct := new(GetSubscription)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
- outstruct.PendingFulfillments = *abi.ConvertType(out[1], new(uint64)).(*uint64)
- outstruct.Owner = *abi.ConvertType(out[2], new(common.Address)).(*common.Address)
- outstruct.Consumers = *abi.ConvertType(out[3], new([]common.Address)).(*[]common.Address)
-
- return *outstruct, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) GetSubscription(subId *big.Int) (GetSubscription,
-
- error) {
- return _VRFCoordinator.Contract.GetSubscription(&_VRFCoordinator.CallOpts, subId)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) GetSubscription(subId *big.Int) (GetSubscription,
-
- error) {
- return _VRFCoordinator.Contract.GetSubscription(&_VRFCoordinator.CallOpts, subId)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) GetSubscriptionLinkBalance(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "getSubscriptionLinkBalance")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) GetSubscriptionLinkBalance() (*big.Int, error) {
- return _VRFCoordinator.Contract.GetSubscriptionLinkBalance(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) GetSubscriptionLinkBalance() (*big.Int, error) {
- return _VRFCoordinator.Contract.GetSubscriptionLinkBalance(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "i_beaconPeriodBlocks")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) IBeaconPeriodBlocks() (*big.Int, error) {
- return _VRFCoordinator.Contract.IBeaconPeriodBlocks(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) IBeaconPeriodBlocks() (*big.Int, error) {
- return _VRFCoordinator.Contract.IBeaconPeriodBlocks(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) ILink(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "i_link")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) ILink() (common.Address, error) {
- return _VRFCoordinator.Contract.ILink(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) ILink() (common.Address, error) {
- return _VRFCoordinator.Contract.ILink(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) MigrationVersion(opts *bind.CallOpts) (uint8, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "migrationVersion")
-
- if err != nil {
- return *new(uint8), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) MigrationVersion() (uint8, error) {
- return _VRFCoordinator.Contract.MigrationVersion(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) MigrationVersion() (uint8, error) {
- return _VRFCoordinator.Contract.MigrationVersion(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) OnMigration(opts *bind.CallOpts, arg0 []byte) error {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "onMigration", arg0)
-
- if err != nil {
- return err
- }
-
- return err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) OnMigration(arg0 []byte) error {
- return _VRFCoordinator.Contract.OnMigration(&_VRFCoordinator.CallOpts, arg0)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) OnMigration(arg0 []byte) error {
- return _VRFCoordinator.Contract.OnMigration(&_VRFCoordinator.CallOpts, arg0)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VRFCoordinator.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 (_VRFCoordinator *VRFCoordinatorSession) Owner() (common.Address, error) {
- return _VRFCoordinator.Contract.Owner(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) Owner() (common.Address, error) {
- return _VRFCoordinator.Contract.Owner(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) SCallbackConfig(opts *bind.CallOpts) (SCallbackConfig,
-
- error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "s_callbackConfig")
-
- outstruct := new(SCallbackConfig)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.MaxCallbackGasLimit = *abi.ConvertType(out[0], new(uint32)).(*uint32)
- outstruct.MaxCallbackArgumentsLength = *abi.ConvertType(out[1], new(uint32)).(*uint32)
-
- return *outstruct, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SCallbackConfig() (SCallbackConfig,
-
- error) {
- return _VRFCoordinator.Contract.SCallbackConfig(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) SCallbackConfig() (SCallbackConfig,
-
- error) {
- return _VRFCoordinator.Contract.SCallbackConfig(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) SCoordinatorConfig(opts *bind.CallOpts) (SCoordinatorConfig,
-
- error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "s_coordinatorConfig")
-
- outstruct := new(SCoordinatorConfig)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.UseReasonableGasPrice = *abi.ConvertType(out[0], new(bool)).(*bool)
- outstruct.ReentrancyLock = *abi.ConvertType(out[1], new(bool)).(*bool)
- outstruct.Paused = *abi.ConvertType(out[2], new(bool)).(*bool)
- outstruct.PremiumPercentage = *abi.ConvertType(out[3], new(uint8)).(*uint8)
- outstruct.UnusedGasPenaltyPercent = *abi.ConvertType(out[4], new(uint8)).(*uint8)
- outstruct.StalenessSeconds = *abi.ConvertType(out[5], new(uint32)).(*uint32)
- outstruct.RedeemableRequestGasOverhead = *abi.ConvertType(out[6], new(uint32)).(*uint32)
- outstruct.CallbackRequestGasOverhead = *abi.ConvertType(out[7], new(uint32)).(*uint32)
- outstruct.ReasonableGasPriceStalenessBlocks = *abi.ConvertType(out[8], new(uint32)).(*uint32)
- outstruct.FallbackWeiPerUnitLink = *abi.ConvertType(out[9], new(*big.Int)).(**big.Int)
-
- return *outstruct, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SCoordinatorConfig() (SCoordinatorConfig,
-
- error) {
- return _VRFCoordinator.Contract.SCoordinatorConfig(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) SCoordinatorConfig() (SCoordinatorConfig,
-
- error) {
- return _VRFCoordinator.Contract.SCoordinatorConfig(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) SPendingRequests(opts *bind.CallOpts, arg0 *big.Int) (SPendingRequests,
-
- error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "s_pendingRequests", arg0)
-
- outstruct := new(SPendingRequests)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.SlotNumber = *abi.ConvertType(out[0], new(uint32)).(*uint32)
- outstruct.ConfirmationDelay = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
- outstruct.NumWords = *abi.ConvertType(out[2], new(uint16)).(*uint16)
- outstruct.Requester = *abi.ConvertType(out[3], new(common.Address)).(*common.Address)
-
- return *outstruct, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SPendingRequests(arg0 *big.Int) (SPendingRequests,
-
- error) {
- return _VRFCoordinator.Contract.SPendingRequests(&_VRFCoordinator.CallOpts, arg0)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) SPendingRequests(arg0 *big.Int) (SPendingRequests,
-
- error) {
- return _VRFCoordinator.Contract.SPendingRequests(&_VRFCoordinator.CallOpts, arg0)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCaller) SProducer(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VRFCoordinator.contract.Call(opts, &out, "s_producer")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SProducer() (common.Address, error) {
- return _VRFCoordinator.Contract.SProducer(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorCallerSession) SProducer() (common.Address, error) {
- return _VRFCoordinator.Contract.SProducer(&_VRFCoordinator.CallOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "acceptOwnership")
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) AcceptOwnership() (*types.Transaction, error) {
- return _VRFCoordinator.Contract.AcceptOwnership(&_VRFCoordinator.TransactOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) AcceptOwnership() (*types.Transaction, error) {
- return _VRFCoordinator.Contract.AcceptOwnership(&_VRFCoordinator.TransactOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subId)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinator.TransactOpts, subId)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinator.TransactOpts, subId)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "addConsumer", subId, consumer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.AddConsumer(&_VRFCoordinator.TransactOpts, subId, consumer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.AddConsumer(&_VRFCoordinator.TransactOpts, subId, consumer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) BatchTransferLink(opts *bind.TransactOpts, recipients []common.Address, paymentsInJuels []*big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "batchTransferLink", recipients, paymentsInJuels)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) BatchTransferLink(recipients []common.Address, paymentsInJuels []*big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.BatchTransferLink(&_VRFCoordinator.TransactOpts, recipients, paymentsInJuels)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) BatchTransferLink(recipients []common.Address, paymentsInJuels []*big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.BatchTransferLink(&_VRFCoordinator.TransactOpts, recipients, paymentsInJuels)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "cancelSubscription", subId, to)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.CancelSubscription(&_VRFCoordinator.TransactOpts, subId, to)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.CancelSubscription(&_VRFCoordinator.TransactOpts, subId, to)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "createSubscription")
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) CreateSubscription() (*types.Transaction, error) {
- return _VRFCoordinator.Contract.CreateSubscription(&_VRFCoordinator.TransactOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) CreateSubscription() (*types.Transaction, error) {
- return _VRFCoordinator.Contract.CreateSubscription(&_VRFCoordinator.TransactOpts)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "deregisterMigratableCoordinator", target)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.DeregisterMigratableCoordinator(&_VRFCoordinator.TransactOpts, target)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.DeregisterMigratableCoordinator(&_VRFCoordinator.TransactOpts, target)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) Migrate(opts *bind.TransactOpts, newCoordinator common.Address, encodedRequest []byte) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "migrate", newCoordinator, encodedRequest)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) Migrate(newCoordinator common.Address, encodedRequest []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.Migrate(&_VRFCoordinator.TransactOpts, newCoordinator, encodedRequest)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) Migrate(newCoordinator common.Address, encodedRequest []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.Migrate(&_VRFCoordinator.TransactOpts, newCoordinator, encodedRequest)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "onTokenTransfer", arg0, amount, data)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.OnTokenTransfer(&_VRFCoordinator.TransactOpts, arg0, amount, data)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.OnTokenTransfer(&_VRFCoordinator.TransactOpts, arg0, amount, data)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) ProcessVRFOutputs(opts *bind.TransactOpts, vrfOutputs []VRFBeaconTypesVRFOutput, juelsPerFeeCoin *big.Int, reasonableGasPrice uint64, blockHeight uint64) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "processVRFOutputs", vrfOutputs, juelsPerFeeCoin, reasonableGasPrice, blockHeight)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) ProcessVRFOutputs(vrfOutputs []VRFBeaconTypesVRFOutput, juelsPerFeeCoin *big.Int, reasonableGasPrice uint64, blockHeight uint64) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.ProcessVRFOutputs(&_VRFCoordinator.TransactOpts, vrfOutputs, juelsPerFeeCoin, reasonableGasPrice, blockHeight)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) ProcessVRFOutputs(vrfOutputs []VRFBeaconTypesVRFOutput, juelsPerFeeCoin *big.Int, reasonableGasPrice uint64, blockHeight uint64) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.ProcessVRFOutputs(&_VRFCoordinator.TransactOpts, vrfOutputs, juelsPerFeeCoin, reasonableGasPrice, blockHeight)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) RedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int, arg2 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "redeemRandomness", subID, requestID, arg2)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) RedeemRandomness(subID *big.Int, requestID *big.Int, arg2 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RedeemRandomness(&_VRFCoordinator.TransactOpts, subID, requestID, arg2)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) RedeemRandomness(subID *big.Int, requestID *big.Int, arg2 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RedeemRandomness(&_VRFCoordinator.TransactOpts, subID, requestID, arg2)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "registerMigratableCoordinator", target)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RegisterMigratableCoordinator(&_VRFCoordinator.TransactOpts, target)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RegisterMigratableCoordinator(&_VRFCoordinator.TransactOpts, target)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "removeConsumer", subId, consumer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RemoveConsumer(&_VRFCoordinator.TransactOpts, subId, consumer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RemoveConsumer(&_VRFCoordinator.TransactOpts, subId, consumer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) RequestRandomness(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, arg3 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "requestRandomness", subID, numWords, confDelay, arg3)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) RequestRandomness(subID *big.Int, numWords uint16, confDelay *big.Int, arg3 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RequestRandomness(&_VRFCoordinator.TransactOpts, subID, numWords, confDelay, arg3)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) RequestRandomness(subID *big.Int, numWords uint16, confDelay *big.Int, arg3 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RequestRandomness(&_VRFCoordinator.TransactOpts, subID, numWords, confDelay, arg3)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) RequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte, arg5 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "requestRandomnessFulfillment", subID, numWords, confDelay, callbackGasLimit, arguments, arg5)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) RequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte, arg5 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RequestRandomnessFulfillment(&_VRFCoordinator.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments, arg5)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) RequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte, arg5 []byte) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RequestRandomnessFulfillment(&_VRFCoordinator.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments, arg5)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subId, newOwner)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinator.TransactOpts, subId, newOwner)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinator.TransactOpts, subId, newOwner)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) SetCallbackConfig(opts *bind.TransactOpts, config VRFCoordinatorCallbackConfig) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "setCallbackConfig", config)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SetCallbackConfig(config VRFCoordinatorCallbackConfig) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetCallbackConfig(&_VRFCoordinator.TransactOpts, config)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetCallbackConfig(config VRFCoordinatorCallbackConfig) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetCallbackConfig(&_VRFCoordinator.TransactOpts, config)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) SetConfirmationDelays(opts *bind.TransactOpts, confDelays [8]*big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "setConfirmationDelays", confDelays)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SetConfirmationDelays(confDelays [8]*big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetConfirmationDelays(&_VRFCoordinator.TransactOpts, confDelays)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetConfirmationDelays(confDelays [8]*big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetConfirmationDelays(&_VRFCoordinator.TransactOpts, confDelays)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) SetCoordinatorConfig(opts *bind.TransactOpts, coordinatorConfig VRFBeaconTypesCoordinatorConfig) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "setCoordinatorConfig", coordinatorConfig)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SetCoordinatorConfig(coordinatorConfig VRFBeaconTypesCoordinatorConfig) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetCoordinatorConfig(&_VRFCoordinator.TransactOpts, coordinatorConfig)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetCoordinatorConfig(coordinatorConfig VRFBeaconTypesCoordinatorConfig) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetCoordinatorConfig(&_VRFCoordinator.TransactOpts, coordinatorConfig)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) SetPauseFlag(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "setPauseFlag", pause)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SetPauseFlag(pause bool) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetPauseFlag(&_VRFCoordinator.TransactOpts, pause)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetPauseFlag(pause bool) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetPauseFlag(&_VRFCoordinator.TransactOpts, pause)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) SetProducer(opts *bind.TransactOpts, producer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "setProducer", producer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) SetProducer(producer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetProducer(&_VRFCoordinator.TransactOpts, producer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetProducer(producer common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.SetProducer(&_VRFCoordinator.TransactOpts, producer)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) TransferLink(opts *bind.TransactOpts, recipient common.Address, juelsAmount *big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "transferLink", recipient, juelsAmount)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) TransferLink(recipient common.Address, juelsAmount *big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.TransferLink(&_VRFCoordinator.TransactOpts, recipient, juelsAmount)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) TransferLink(recipient common.Address, juelsAmount *big.Int) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.TransferLink(&_VRFCoordinator.TransactOpts, recipient, juelsAmount)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.contract.Transact(opts, "transferOwnership", to)
-}
-
-func (_VRFCoordinator *VRFCoordinatorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.TransferOwnership(&_VRFCoordinator.TransactOpts, to)
-}
-
-func (_VRFCoordinator *VRFCoordinatorTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _VRFCoordinator.Contract.TransferOwnership(&_VRFCoordinator.TransactOpts, to)
-}
-
-type VRFCoordinatorCallbackConfigSetIterator struct {
- Event *VRFCoordinatorCallbackConfigSet
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorCallbackConfigSetIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorCallbackConfigSet)
- 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(VRFCoordinatorCallbackConfigSet)
- 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 *VRFCoordinatorCallbackConfigSetIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorCallbackConfigSetIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorCallbackConfigSet struct {
- NewConfig VRFCoordinatorCallbackConfig
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterCallbackConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorCallbackConfigSetIterator, error) {
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "CallbackConfigSet")
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorCallbackConfigSetIterator{contract: _VRFCoordinator.contract, event: "CallbackConfigSet", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchCallbackConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCallbackConfigSet) (event.Subscription, error) {
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "CallbackConfigSet")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorCallbackConfigSet)
- if err := _VRFCoordinator.contract.UnpackLog(event, "CallbackConfigSet", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseCallbackConfigSet(log types.Log) (*VRFCoordinatorCallbackConfigSet, error) {
- event := new(VRFCoordinatorCallbackConfigSet)
- if err := _VRFCoordinator.contract.UnpackLog(event, "CallbackConfigSet", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorCoordinatorConfigSetIterator struct {
- Event *VRFCoordinatorCoordinatorConfigSet
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorCoordinatorConfigSetIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorCoordinatorConfigSet)
- 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(VRFCoordinatorCoordinatorConfigSet)
- 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 *VRFCoordinatorCoordinatorConfigSetIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorCoordinatorConfigSetIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorCoordinatorConfigSet struct {
- CoordinatorConfig VRFBeaconTypesCoordinatorConfig
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterCoordinatorConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorConfigSetIterator, error) {
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "CoordinatorConfigSet")
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorCoordinatorConfigSetIterator{contract: _VRFCoordinator.contract, event: "CoordinatorConfigSet", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchCoordinatorConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorConfigSet) (event.Subscription, error) {
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "CoordinatorConfigSet")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorCoordinatorConfigSet)
- if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorConfigSet", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseCoordinatorConfigSet(log types.Log) (*VRFCoordinatorCoordinatorConfigSet, error) {
- event := new(VRFCoordinatorCoordinatorConfigSet)
- if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorConfigSet", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorCoordinatorDeregisteredIterator struct {
- Event *VRFCoordinatorCoordinatorDeregistered
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorCoordinatorDeregisteredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorCoordinatorDeregistered)
- 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(VRFCoordinatorCoordinatorDeregistered)
- 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 *VRFCoordinatorCoordinatorDeregisteredIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorCoordinatorDeregisteredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorCoordinatorDeregistered struct {
- CoordinatorAddress common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorDeregisteredIterator, error) {
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "CoordinatorDeregistered")
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorCoordinatorDeregisteredIterator{contract: _VRFCoordinator.contract, event: "CoordinatorDeregistered", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorDeregistered) (event.Subscription, error) {
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "CoordinatorDeregistered")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorCoordinatorDeregistered)
- if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorDeregistered", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorCoordinatorDeregistered, error) {
- event := new(VRFCoordinatorCoordinatorDeregistered)
- if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorCoordinatorRegisteredIterator struct {
- Event *VRFCoordinatorCoordinatorRegistered
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorCoordinatorRegisteredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorCoordinatorRegistered)
- 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(VRFCoordinatorCoordinatorRegistered)
- 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 *VRFCoordinatorCoordinatorRegisteredIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorCoordinatorRegisteredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorCoordinatorRegistered struct {
- CoordinatorAddress common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorRegisteredIterator, error) {
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "CoordinatorRegistered")
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorCoordinatorRegisteredIterator{contract: _VRFCoordinator.contract, event: "CoordinatorRegistered", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorRegistered) (event.Subscription, error) {
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "CoordinatorRegistered")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorCoordinatorRegistered)
- if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorRegistered", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorCoordinatorRegistered, error) {
- event := new(VRFCoordinatorCoordinatorRegistered)
- if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorMigrationCompletedIterator struct {
- Event *VRFCoordinatorMigrationCompleted
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorMigrationCompletedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorMigrationCompleted)
- 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(VRFCoordinatorMigrationCompleted)
- 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 *VRFCoordinatorMigrationCompletedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorMigrationCompletedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorMigrationCompleted struct {
- NewVersion uint8
- NewCoordinator common.Address
- SubID *big.Int
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterMigrationCompleted(opts *bind.FilterOpts, newVersion []uint8, subID []*big.Int) (*VRFCoordinatorMigrationCompletedIterator, error) {
-
- var newVersionRule []interface{}
- for _, newVersionItem := range newVersion {
- newVersionRule = append(newVersionRule, newVersionItem)
- }
-
- var subIDRule []interface{}
- for _, subIDItem := range subID {
- subIDRule = append(subIDRule, subIDItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "MigrationCompleted", newVersionRule, subIDRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorMigrationCompletedIterator{contract: _VRFCoordinator.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorMigrationCompleted, newVersion []uint8, subID []*big.Int) (event.Subscription, error) {
-
- var newVersionRule []interface{}
- for _, newVersionItem := range newVersion {
- newVersionRule = append(newVersionRule, newVersionItem)
- }
-
- var subIDRule []interface{}
- for _, subIDItem := range subID {
- subIDRule = append(subIDRule, subIDItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "MigrationCompleted", newVersionRule, subIDRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorMigrationCompleted)
- if err := _VRFCoordinator.contract.UnpackLog(event, "MigrationCompleted", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseMigrationCompleted(log types.Log) (*VRFCoordinatorMigrationCompleted, error) {
- event := new(VRFCoordinatorMigrationCompleted)
- if err := _VRFCoordinator.contract.UnpackLog(event, "MigrationCompleted", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorOutputsServedIterator struct {
- Event *VRFCoordinatorOutputsServed
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorOutputsServedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorOutputsServed)
- 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(VRFCoordinatorOutputsServed)
- 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 *VRFCoordinatorOutputsServedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorOutputsServedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorOutputsServed struct {
- RecentBlockHeight uint64
- JuelsPerFeeCoin *big.Int
- ReasonableGasPrice uint64
- OutputsServed []VRFBeaconTypesOutputServed
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterOutputsServed(opts *bind.FilterOpts) (*VRFCoordinatorOutputsServedIterator, error) {
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "OutputsServed")
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorOutputsServedIterator{contract: _VRFCoordinator.contract, event: "OutputsServed", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchOutputsServed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOutputsServed) (event.Subscription, error) {
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "OutputsServed")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorOutputsServed)
- if err := _VRFCoordinator.contract.UnpackLog(event, "OutputsServed", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseOutputsServed(log types.Log) (*VRFCoordinatorOutputsServed, error) {
- event := new(VRFCoordinatorOutputsServed)
- if err := _VRFCoordinator.contract.UnpackLog(event, "OutputsServed", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorOwnershipTransferRequestedIterator struct {
- Event *VRFCoordinatorOwnershipTransferRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorOwnershipTransferRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorOwnershipTransferRequested)
- 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(VRFCoordinatorOwnershipTransferRequested)
- 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 *VRFCoordinatorOwnershipTransferRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorOwnershipTransferRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorOwnershipTransferRequested struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorOwnershipTransferRequestedIterator, 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 := _VRFCoordinator.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorOwnershipTransferRequestedIterator{contract: _VRFCoordinator.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOwnershipTransferRequested, 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 := _VRFCoordinator.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(VRFCoordinatorOwnershipTransferRequested)
- if err := _VRFCoordinator.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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorOwnershipTransferRequested, error) {
- event := new(VRFCoordinatorOwnershipTransferRequested)
- if err := _VRFCoordinator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorOwnershipTransferredIterator struct {
- Event *VRFCoordinatorOwnershipTransferred
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorOwnershipTransferredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorOwnershipTransferred)
- 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(VRFCoordinatorOwnershipTransferred)
- 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 *VRFCoordinatorOwnershipTransferredIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorOwnershipTransferredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorOwnershipTransferred struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorOwnershipTransferredIterator, 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 := _VRFCoordinator.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorOwnershipTransferredIterator{contract: _VRFCoordinator.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOwnershipTransferred, 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 := _VRFCoordinator.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(VRFCoordinatorOwnershipTransferred)
- if err := _VRFCoordinator.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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorOwnershipTransferred, error) {
- event := new(VRFCoordinatorOwnershipTransferred)
- if err := _VRFCoordinator.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorPauseFlagChangedIterator struct {
- Event *VRFCoordinatorPauseFlagChanged
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorPauseFlagChangedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorPauseFlagChanged)
- 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(VRFCoordinatorPauseFlagChanged)
- 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 *VRFCoordinatorPauseFlagChangedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorPauseFlagChangedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorPauseFlagChanged struct {
- Paused bool
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterPauseFlagChanged(opts *bind.FilterOpts) (*VRFCoordinatorPauseFlagChangedIterator, error) {
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "PauseFlagChanged")
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorPauseFlagChangedIterator{contract: _VRFCoordinator.contract, event: "PauseFlagChanged", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchPauseFlagChanged(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorPauseFlagChanged) (event.Subscription, error) {
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "PauseFlagChanged")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorPauseFlagChanged)
- if err := _VRFCoordinator.contract.UnpackLog(event, "PauseFlagChanged", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParsePauseFlagChanged(log types.Log) (*VRFCoordinatorPauseFlagChanged, error) {
- event := new(VRFCoordinatorPauseFlagChanged)
- if err := _VRFCoordinator.contract.UnpackLog(event, "PauseFlagChanged", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorRandomWordsFulfilledIterator struct {
- Event *VRFCoordinatorRandomWordsFulfilled
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorRandomWordsFulfilledIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorRandomWordsFulfilled)
- 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(VRFCoordinatorRandomWordsFulfilled)
- 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 *VRFCoordinatorRandomWordsFulfilledIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorRandomWordsFulfilledIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorRandomWordsFulfilled struct {
- RequestIDs []*big.Int
- SuccessfulFulfillment []byte
- TruncatedErrorData [][]byte
- SubBalances []*big.Int
- SubIDs []*big.Int
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts) (*VRFCoordinatorRandomWordsFulfilledIterator, error) {
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "RandomWordsFulfilled")
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorRandomWordsFulfilledIterator{contract: _VRFCoordinator.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomWordsFulfilled) (event.Subscription, error) {
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "RandomWordsFulfilled")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorRandomWordsFulfilled)
- if err := _VRFCoordinator.contract.UnpackLog(event, "RandomWordsFulfilled", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorRandomWordsFulfilled, error) {
- event := new(VRFCoordinatorRandomWordsFulfilled)
- if err := _VRFCoordinator.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorRandomnessFulfillmentRequestedIterator struct {
- Event *VRFCoordinatorRandomnessFulfillmentRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorRandomnessFulfillmentRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorRandomnessFulfillmentRequested)
- 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(VRFCoordinatorRandomnessFulfillmentRequested)
- 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 *VRFCoordinatorRandomnessFulfillmentRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorRandomnessFulfillmentRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorRandomnessFulfillmentRequested struct {
- RequestID *big.Int
- Requester common.Address
- NextBeaconOutputHeight uint64
- ConfDelay *big.Int
- SubID *big.Int
- NumWords uint16
- GasAllowance uint32
- GasPrice *big.Int
- WeiPerUnitLink *big.Int
- Arguments []byte
- CostJuels *big.Int
- NewSubBalance *big.Int
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterRandomnessFulfillmentRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFCoordinatorRandomnessFulfillmentRequestedIterator, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "RandomnessFulfillmentRequested", requestIDRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorRandomnessFulfillmentRequestedIterator{contract: _VRFCoordinator.contract, event: "RandomnessFulfillmentRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchRandomnessFulfillmentRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessFulfillmentRequested, requestID []*big.Int) (event.Subscription, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "RandomnessFulfillmentRequested", requestIDRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorRandomnessFulfillmentRequested)
- if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessFulfillmentRequested", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseRandomnessFulfillmentRequested(log types.Log) (*VRFCoordinatorRandomnessFulfillmentRequested, error) {
- event := new(VRFCoordinatorRandomnessFulfillmentRequested)
- if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessFulfillmentRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorRandomnessRedeemedIterator struct {
- Event *VRFCoordinatorRandomnessRedeemed
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorRandomnessRedeemedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorRandomnessRedeemed)
- 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(VRFCoordinatorRandomnessRedeemed)
- 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 *VRFCoordinatorRandomnessRedeemedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorRandomnessRedeemedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorRandomnessRedeemed struct {
- RequestID *big.Int
- Requester common.Address
- SubID *big.Int
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterRandomnessRedeemed(opts *bind.FilterOpts, requestID []*big.Int, requester []common.Address) (*VRFCoordinatorRandomnessRedeemedIterator, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
- var requesterRule []interface{}
- for _, requesterItem := range requester {
- requesterRule = append(requesterRule, requesterItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "RandomnessRedeemed", requestIDRule, requesterRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorRandomnessRedeemedIterator{contract: _VRFCoordinator.contract, event: "RandomnessRedeemed", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchRandomnessRedeemed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessRedeemed, requestID []*big.Int, requester []common.Address) (event.Subscription, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
- var requesterRule []interface{}
- for _, requesterItem := range requester {
- requesterRule = append(requesterRule, requesterItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "RandomnessRedeemed", requestIDRule, requesterRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorRandomnessRedeemed)
- if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessRedeemed", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseRandomnessRedeemed(log types.Log) (*VRFCoordinatorRandomnessRedeemed, error) {
- event := new(VRFCoordinatorRandomnessRedeemed)
- if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessRedeemed", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorRandomnessRequestedIterator struct {
- Event *VRFCoordinatorRandomnessRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorRandomnessRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorRandomnessRequested)
- 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(VRFCoordinatorRandomnessRequested)
- 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 *VRFCoordinatorRandomnessRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorRandomnessRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorRandomnessRequested struct {
- RequestID *big.Int
- Requester common.Address
- NextBeaconOutputHeight uint64
- ConfDelay *big.Int
- SubID *big.Int
- NumWords uint16
- CostJuels *big.Int
- NewSubBalance *big.Int
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterRandomnessRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFCoordinatorRandomnessRequestedIterator, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "RandomnessRequested", requestIDRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorRandomnessRequestedIterator{contract: _VRFCoordinator.contract, event: "RandomnessRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchRandomnessRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessRequested, requestID []*big.Int) (event.Subscription, error) {
-
- var requestIDRule []interface{}
- for _, requestIDItem := range requestID {
- requestIDRule = append(requestIDRule, requestIDItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "RandomnessRequested", requestIDRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorRandomnessRequested)
- if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessRequested", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseRandomnessRequested(log types.Log) (*VRFCoordinatorRandomnessRequested, error) {
- event := new(VRFCoordinatorRandomnessRequested)
- if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorSubscriptionCanceledIterator struct {
- Event *VRFCoordinatorSubscriptionCanceled
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorSubscriptionCanceledIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorSubscriptionCanceled)
- 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(VRFCoordinatorSubscriptionCanceled)
- 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 *VRFCoordinatorSubscriptionCanceledIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorSubscriptionCanceledIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorSubscriptionCanceled struct {
- SubId *big.Int
- To common.Address
- Amount *big.Int
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionCanceledIterator, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionCanceled", subIdRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorSubscriptionCanceledIterator{contract: _VRFCoordinator.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionCanceled, subId []*big.Int) (event.Subscription, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionCanceled", subIdRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorSubscriptionCanceled)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionCanceled", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorSubscriptionCanceled, error) {
- event := new(VRFCoordinatorSubscriptionCanceled)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorSubscriptionConsumerAddedIterator struct {
- Event *VRFCoordinatorSubscriptionConsumerAdded
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorSubscriptionConsumerAddedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorSubscriptionConsumerAdded)
- 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(VRFCoordinatorSubscriptionConsumerAdded)
- 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 *VRFCoordinatorSubscriptionConsumerAddedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorSubscriptionConsumerAddedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorSubscriptionConsumerAdded struct {
- SubId *big.Int
- Consumer common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionConsumerAddedIterator, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subIdRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorSubscriptionConsumerAddedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subIdRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorSubscriptionConsumerAdded)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionConsumerAdded", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorSubscriptionConsumerAdded, error) {
- event := new(VRFCoordinatorSubscriptionConsumerAdded)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorSubscriptionConsumerRemovedIterator struct {
- Event *VRFCoordinatorSubscriptionConsumerRemoved
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorSubscriptionConsumerRemovedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorSubscriptionConsumerRemoved)
- 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(VRFCoordinatorSubscriptionConsumerRemoved)
- 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 *VRFCoordinatorSubscriptionConsumerRemovedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorSubscriptionConsumerRemovedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorSubscriptionConsumerRemoved struct {
- SubId *big.Int
- Consumer common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionConsumerRemovedIterator, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subIdRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorSubscriptionConsumerRemovedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subIdRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorSubscriptionConsumerRemoved)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionConsumerRemoved", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorSubscriptionConsumerRemoved, error) {
- event := new(VRFCoordinatorSubscriptionConsumerRemoved)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorSubscriptionCreatedIterator struct {
- Event *VRFCoordinatorSubscriptionCreated
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorSubscriptionCreatedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorSubscriptionCreated)
- 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(VRFCoordinatorSubscriptionCreated)
- 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 *VRFCoordinatorSubscriptionCreatedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorSubscriptionCreatedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorSubscriptionCreated struct {
- SubId *big.Int
- Owner common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int, owner []common.Address) (*VRFCoordinatorSubscriptionCreatedIterator, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
- var ownerRule []interface{}
- for _, ownerItem := range owner {
- ownerRule = append(ownerRule, ownerItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionCreated", subIdRule, ownerRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorSubscriptionCreatedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionCreated, subId []*big.Int, owner []common.Address) (event.Subscription, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
- var ownerRule []interface{}
- for _, ownerItem := range owner {
- ownerRule = append(ownerRule, ownerItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionCreated", subIdRule, ownerRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorSubscriptionCreated)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionCreated", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorSubscriptionCreated, error) {
- event := new(VRFCoordinatorSubscriptionCreated)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorSubscriptionFundedIterator struct {
- Event *VRFCoordinatorSubscriptionFunded
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorSubscriptionFundedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorSubscriptionFunded)
- 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(VRFCoordinatorSubscriptionFunded)
- 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 *VRFCoordinatorSubscriptionFundedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorSubscriptionFundedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorSubscriptionFunded struct {
- SubId *big.Int
- OldBalance *big.Int
- NewBalance *big.Int
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionFundedIterator, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionFunded", subIdRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorSubscriptionFundedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionFunded, subId []*big.Int) (event.Subscription, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionFunded", subIdRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorSubscriptionFunded)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionFunded", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorSubscriptionFunded, error) {
- event := new(VRFCoordinatorSubscriptionFunded)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorSubscriptionOwnerTransferRequestedIterator struct {
- Event *VRFCoordinatorSubscriptionOwnerTransferRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorSubscriptionOwnerTransferRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorSubscriptionOwnerTransferRequested)
- 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(VRFCoordinatorSubscriptionOwnerTransferRequested)
- 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 *VRFCoordinatorSubscriptionOwnerTransferRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorSubscriptionOwnerTransferRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorSubscriptionOwnerTransferRequested struct {
- SubId *big.Int
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionOwnerTransferRequestedIterator, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorSubscriptionOwnerTransferRequestedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorSubscriptionOwnerTransferRequested)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorSubscriptionOwnerTransferRequested, error) {
- event := new(VRFCoordinatorSubscriptionOwnerTransferRequested)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VRFCoordinatorSubscriptionOwnerTransferredIterator struct {
- Event *VRFCoordinatorSubscriptionOwnerTransferred
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VRFCoordinatorSubscriptionOwnerTransferredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VRFCoordinatorSubscriptionOwnerTransferred)
- 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(VRFCoordinatorSubscriptionOwnerTransferred)
- 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 *VRFCoordinatorSubscriptionOwnerTransferredIterator) Error() error {
- return it.fail
-}
-
-func (it *VRFCoordinatorSubscriptionOwnerTransferredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VRFCoordinatorSubscriptionOwnerTransferred struct {
- SubId *big.Int
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionOwnerTransferredIterator, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subIdRule)
- if err != nil {
- return nil, err
- }
- return &VRFCoordinatorSubscriptionOwnerTransferredIterator{contract: _VRFCoordinator.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil
-}
-
-func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) {
-
- var subIdRule []interface{}
- for _, subIdItem := range subId {
- subIdRule = append(subIdRule, subIdItem)
- }
-
- logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subIdRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VRFCoordinatorSubscriptionOwnerTransferred)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionOwnerTransferred", 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 (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorSubscriptionOwnerTransferred, error) {
- event := new(VRFCoordinatorSubscriptionOwnerTransferred)
- if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type GetSubscription struct {
- Balance *big.Int
- PendingFulfillments uint64
- Owner common.Address
- Consumers []common.Address
-}
-type SCallbackConfig struct {
- MaxCallbackGasLimit uint32
- MaxCallbackArgumentsLength uint32
-}
-type SCoordinatorConfig struct {
- UseReasonableGasPrice bool
- ReentrancyLock bool
- Paused bool
- PremiumPercentage uint8
- UnusedGasPenaltyPercent uint8
- StalenessSeconds uint32
- RedeemableRequestGasOverhead uint32
- CallbackRequestGasOverhead uint32
- ReasonableGasPriceStalenessBlocks uint32
- FallbackWeiPerUnitLink *big.Int
-}
-type SPendingRequests struct {
- SlotNumber uint32
- ConfirmationDelay *big.Int
- NumWords uint16
- Requester common.Address
-}
-
-func (_VRFCoordinator *VRFCoordinator) ParseLog(log types.Log) (generated.AbigenLog, error) {
- switch log.Topics[0] {
- case _VRFCoordinator.abi.Events["CallbackConfigSet"].ID:
- return _VRFCoordinator.ParseCallbackConfigSet(log)
- case _VRFCoordinator.abi.Events["CoordinatorConfigSet"].ID:
- return _VRFCoordinator.ParseCoordinatorConfigSet(log)
- case _VRFCoordinator.abi.Events["CoordinatorDeregistered"].ID:
- return _VRFCoordinator.ParseCoordinatorDeregistered(log)
- case _VRFCoordinator.abi.Events["CoordinatorRegistered"].ID:
- return _VRFCoordinator.ParseCoordinatorRegistered(log)
- case _VRFCoordinator.abi.Events["MigrationCompleted"].ID:
- return _VRFCoordinator.ParseMigrationCompleted(log)
- case _VRFCoordinator.abi.Events["OutputsServed"].ID:
- return _VRFCoordinator.ParseOutputsServed(log)
- case _VRFCoordinator.abi.Events["OwnershipTransferRequested"].ID:
- return _VRFCoordinator.ParseOwnershipTransferRequested(log)
- case _VRFCoordinator.abi.Events["OwnershipTransferred"].ID:
- return _VRFCoordinator.ParseOwnershipTransferred(log)
- case _VRFCoordinator.abi.Events["PauseFlagChanged"].ID:
- return _VRFCoordinator.ParsePauseFlagChanged(log)
- case _VRFCoordinator.abi.Events["RandomWordsFulfilled"].ID:
- return _VRFCoordinator.ParseRandomWordsFulfilled(log)
- case _VRFCoordinator.abi.Events["RandomnessFulfillmentRequested"].ID:
- return _VRFCoordinator.ParseRandomnessFulfillmentRequested(log)
- case _VRFCoordinator.abi.Events["RandomnessRedeemed"].ID:
- return _VRFCoordinator.ParseRandomnessRedeemed(log)
- case _VRFCoordinator.abi.Events["RandomnessRequested"].ID:
- return _VRFCoordinator.ParseRandomnessRequested(log)
- case _VRFCoordinator.abi.Events["SubscriptionCanceled"].ID:
- return _VRFCoordinator.ParseSubscriptionCanceled(log)
- case _VRFCoordinator.abi.Events["SubscriptionConsumerAdded"].ID:
- return _VRFCoordinator.ParseSubscriptionConsumerAdded(log)
- case _VRFCoordinator.abi.Events["SubscriptionConsumerRemoved"].ID:
- return _VRFCoordinator.ParseSubscriptionConsumerRemoved(log)
- case _VRFCoordinator.abi.Events["SubscriptionCreated"].ID:
- return _VRFCoordinator.ParseSubscriptionCreated(log)
- case _VRFCoordinator.abi.Events["SubscriptionFunded"].ID:
- return _VRFCoordinator.ParseSubscriptionFunded(log)
- case _VRFCoordinator.abi.Events["SubscriptionOwnerTransferRequested"].ID:
- return _VRFCoordinator.ParseSubscriptionOwnerTransferRequested(log)
- case _VRFCoordinator.abi.Events["SubscriptionOwnerTransferred"].ID:
- return _VRFCoordinator.ParseSubscriptionOwnerTransferred(log)
-
- default:
- return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
- }
-}
-
-func (VRFCoordinatorCallbackConfigSet) Topic() common.Hash {
- return common.HexToHash("0x0cc54509a45ab33cd67614d4a2892c083ecf8fb43b9d29f6ea8130b9023e51df")
-}
-
-func (VRFCoordinatorCoordinatorConfigSet) Topic() common.Hash {
- return common.HexToHash("0x0028d3a46e95e67def989d41c66eb331add9809460b95b5fb4eb006157728fc5")
-}
-
-func (VRFCoordinatorCoordinatorDeregistered) Topic() common.Hash {
- return common.HexToHash("0xf80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37")
-}
-
-func (VRFCoordinatorCoordinatorRegistered) Topic() common.Hash {
- return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625")
-}
-
-func (VRFCoordinatorMigrationCompleted) Topic() common.Hash {
- return common.HexToHash("0xbd89b747474d3fc04664dfbd1d56ae7ffbe46ee097cdb9979c13916bb76269ce")
-}
-
-func (VRFCoordinatorOutputsServed) Topic() common.Hash {
- return common.HexToHash("0xf10ea936d00579b4c52035ee33bf46929646b3aa87554c565d8fb2c7aa549c44")
-}
-
-func (VRFCoordinatorOwnershipTransferRequested) Topic() common.Hash {
- return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
-}
-
-func (VRFCoordinatorOwnershipTransferred) Topic() common.Hash {
- return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
-}
-
-func (VRFCoordinatorPauseFlagChanged) Topic() common.Hash {
- return common.HexToHash("0x49ba7c1de2d8853088b6270e43df2118516b217f38b917dd2b80dea360860fbe")
-}
-
-func (VRFCoordinatorRandomWordsFulfilled) Topic() common.Hash {
- return common.HexToHash("0x8f79f730779e875ce76c428039cc2052b5b5918c2a55c598fab251c1198aec54")
-}
-
-func (VRFCoordinatorRandomnessFulfillmentRequested) Topic() common.Hash {
- return common.HexToHash("0x01872fb9c7d6d68af06a17347935e04412da302a377224c205e672c26e18c37f")
-}
-
-func (VRFCoordinatorRandomnessRedeemed) Topic() common.Hash {
- return common.HexToHash("0x16f3f633197fafab10a5df69e6f3f2f7f20092f08d8d47de0a91c0f4b96a1a25")
-}
-
-func (VRFCoordinatorRandomnessRequested) Topic() common.Hash {
- return common.HexToHash("0xb7933fba96b6b452eb44f99fdc08052a45dff82363d59abaff0456931c3d2459")
-}
-
-func (VRFCoordinatorSubscriptionCanceled) Topic() common.Hash {
- return common.HexToHash("0x3784f77e8e883de95b5d47cd713ced01229fa74d118c0a462224bcb0516d43f1")
-}
-
-func (VRFCoordinatorSubscriptionConsumerAdded) Topic() common.Hash {
- return common.HexToHash("0x1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1")
-}
-
-func (VRFCoordinatorSubscriptionConsumerRemoved) Topic() common.Hash {
- return common.HexToHash("0x32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7")
-}
-
-func (VRFCoordinatorSubscriptionCreated) Topic() common.Hash {
- return common.HexToHash("0x1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d")
-}
-
-func (VRFCoordinatorSubscriptionFunded) Topic() common.Hash {
- return common.HexToHash("0x1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a")
-}
-
-func (VRFCoordinatorSubscriptionOwnerTransferRequested) Topic() common.Hash {
- return common.HexToHash("0x21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1")
-}
-
-func (VRFCoordinatorSubscriptionOwnerTransferred) Topic() common.Hash {
- return common.HexToHash("0xd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386")
-}
-
-func (_VRFCoordinator *VRFCoordinator) Address() common.Address {
- return _VRFCoordinator.address
-}
-
-type VRFCoordinatorInterface interface {
- MAXCONSUMERS(opts *bind.CallOpts) (uint16, error)
-
- MAXNUMWORDS(opts *bind.CallOpts) (*big.Int, error)
-
- NUMCONFDELAYS(opts *bind.CallOpts) (uint8, error)
-
- GetCallbackMemo(opts *bind.CallOpts, requestId *big.Int) ([32]byte, error)
-
- GetConfirmationDelays(opts *bind.CallOpts) ([8]*big.Int, error)
-
- GetFee(opts *bind.CallOpts, arg0 *big.Int, arg1 []byte) (*big.Int, error)
-
- GetFulfillmentFee(opts *bind.CallOpts, arg0 *big.Int, callbackGasLimit uint32, arguments []byte, arg3 []byte) (*big.Int, error)
-
- GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription,
-
- error)
-
- GetSubscriptionLinkBalance(opts *bind.CallOpts) (*big.Int, error)
-
- IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error)
-
- ILink(opts *bind.CallOpts) (common.Address, error)
-
- MigrationVersion(opts *bind.CallOpts) (uint8, error)
-
- OnMigration(opts *bind.CallOpts, arg0 []byte) error
-
- Owner(opts *bind.CallOpts) (common.Address, error)
-
- SCallbackConfig(opts *bind.CallOpts) (SCallbackConfig,
-
- error)
-
- SCoordinatorConfig(opts *bind.CallOpts) (SCoordinatorConfig,
-
- error)
-
- SPendingRequests(opts *bind.CallOpts, arg0 *big.Int) (SPendingRequests,
-
- error)
-
- SProducer(opts *bind.CallOpts) (common.Address, error)
-
- AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
-
- AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error)
-
- AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error)
-
- BatchTransferLink(opts *bind.TransactOpts, recipients []common.Address, paymentsInJuels []*big.Int) (*types.Transaction, error)
-
- CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error)
-
- CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error)
-
- DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error)
-
- Migrate(opts *bind.TransactOpts, newCoordinator common.Address, encodedRequest []byte) (*types.Transaction, error)
-
- OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error)
-
- ProcessVRFOutputs(opts *bind.TransactOpts, vrfOutputs []VRFBeaconTypesVRFOutput, juelsPerFeeCoin *big.Int, reasonableGasPrice uint64, blockHeight uint64) (*types.Transaction, error)
-
- RedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int, arg2 []byte) (*types.Transaction, error)
-
- RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error)
-
- RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error)
-
- RequestRandomness(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, arg3 []byte) (*types.Transaction, error)
-
- RequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte, arg5 []byte) (*types.Transaction, error)
-
- RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error)
-
- SetCallbackConfig(opts *bind.TransactOpts, config VRFCoordinatorCallbackConfig) (*types.Transaction, error)
-
- SetConfirmationDelays(opts *bind.TransactOpts, confDelays [8]*big.Int) (*types.Transaction, error)
-
- SetCoordinatorConfig(opts *bind.TransactOpts, coordinatorConfig VRFBeaconTypesCoordinatorConfig) (*types.Transaction, error)
-
- SetPauseFlag(opts *bind.TransactOpts, pause bool) (*types.Transaction, error)
-
- SetProducer(opts *bind.TransactOpts, producer common.Address) (*types.Transaction, error)
-
- TransferLink(opts *bind.TransactOpts, recipient common.Address, juelsAmount *big.Int) (*types.Transaction, error)
-
- TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
-
- FilterCallbackConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorCallbackConfigSetIterator, error)
-
- WatchCallbackConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCallbackConfigSet) (event.Subscription, error)
-
- ParseCallbackConfigSet(log types.Log) (*VRFCoordinatorCallbackConfigSet, error)
-
- FilterCoordinatorConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorConfigSetIterator, error)
-
- WatchCoordinatorConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorConfigSet) (event.Subscription, error)
-
- ParseCoordinatorConfigSet(log types.Log) (*VRFCoordinatorCoordinatorConfigSet, error)
-
- FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorDeregisteredIterator, error)
-
- WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorDeregistered) (event.Subscription, error)
-
- ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorCoordinatorDeregistered, error)
-
- FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorRegisteredIterator, error)
-
- WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorRegistered) (event.Subscription, error)
-
- ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorCoordinatorRegistered, error)
-
- FilterMigrationCompleted(opts *bind.FilterOpts, newVersion []uint8, subID []*big.Int) (*VRFCoordinatorMigrationCompletedIterator, error)
-
- WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorMigrationCompleted, newVersion []uint8, subID []*big.Int) (event.Subscription, error)
-
- ParseMigrationCompleted(log types.Log) (*VRFCoordinatorMigrationCompleted, error)
-
- FilterOutputsServed(opts *bind.FilterOpts) (*VRFCoordinatorOutputsServedIterator, error)
-
- WatchOutputsServed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOutputsServed) (event.Subscription, error)
-
- ParseOutputsServed(log types.Log) (*VRFCoordinatorOutputsServed, error)
-
- FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorOwnershipTransferRequestedIterator, error)
-
- WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorOwnershipTransferRequested, error)
-
- FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorOwnershipTransferredIterator, error)
-
- WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorOwnershipTransferred, error)
-
- FilterPauseFlagChanged(opts *bind.FilterOpts) (*VRFCoordinatorPauseFlagChangedIterator, error)
-
- WatchPauseFlagChanged(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorPauseFlagChanged) (event.Subscription, error)
-
- ParsePauseFlagChanged(log types.Log) (*VRFCoordinatorPauseFlagChanged, error)
-
- FilterRandomWordsFulfilled(opts *bind.FilterOpts) (*VRFCoordinatorRandomWordsFulfilledIterator, error)
-
- WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomWordsFulfilled) (event.Subscription, error)
-
- ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorRandomWordsFulfilled, error)
-
- FilterRandomnessFulfillmentRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFCoordinatorRandomnessFulfillmentRequestedIterator, error)
-
- WatchRandomnessFulfillmentRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessFulfillmentRequested, requestID []*big.Int) (event.Subscription, error)
-
- ParseRandomnessFulfillmentRequested(log types.Log) (*VRFCoordinatorRandomnessFulfillmentRequested, error)
-
- FilterRandomnessRedeemed(opts *bind.FilterOpts, requestID []*big.Int, requester []common.Address) (*VRFCoordinatorRandomnessRedeemedIterator, error)
-
- WatchRandomnessRedeemed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessRedeemed, requestID []*big.Int, requester []common.Address) (event.Subscription, error)
-
- ParseRandomnessRedeemed(log types.Log) (*VRFCoordinatorRandomnessRedeemed, error)
-
- FilterRandomnessRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFCoordinatorRandomnessRequestedIterator, error)
-
- WatchRandomnessRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessRequested, requestID []*big.Int) (event.Subscription, error)
-
- ParseRandomnessRequested(log types.Log) (*VRFCoordinatorRandomnessRequested, error)
-
- FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionCanceledIterator, error)
-
- WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionCanceled, subId []*big.Int) (event.Subscription, error)
-
- ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorSubscriptionCanceled, error)
-
- FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionConsumerAddedIterator, error)
-
- WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error)
-
- ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorSubscriptionConsumerAdded, error)
-
- FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionConsumerRemovedIterator, error)
-
- WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error)
-
- ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorSubscriptionConsumerRemoved, error)
-
- FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int, owner []common.Address) (*VRFCoordinatorSubscriptionCreatedIterator, error)
-
- WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionCreated, subId []*big.Int, owner []common.Address) (event.Subscription, error)
-
- ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorSubscriptionCreated, error)
-
- FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionFundedIterator, error)
-
- WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionFunded, subId []*big.Int) (event.Subscription, error)
-
- ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorSubscriptionFunded, error)
-
- FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionOwnerTransferRequestedIterator, error)
-
- WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error)
-
- ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorSubscriptionOwnerTransferRequested, error)
-
- FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionOwnerTransferredIterator, error)
-
- WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error)
-
- ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorSubscriptionOwnerTransferred, error)
-
- ParseLog(log types.Log) (generated.AbigenLog, error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/ocr2vrf/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ocr2vrf/generation/generated-wrapper-dependency-versions-do-not-edit.txt
deleted file mode 100644
index ce0b1a09702..00000000000
--- a/core/gethwrappers/ocr2vrf/generation/generated-wrapper-dependency-versions-do-not-edit.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-GETH_VERSION: 1.12.0
-dkg: ../../../contracts/solc/v0.8.19/DKG.abi ../../../contracts/solc/v0.8.19/DKG.bin 02549733c46e50ba393c2521e39d4ec55b6a5d9a66baf4406b1a515b20470425
-load_test_beacon_consumer: ../../../contracts/solc/v0.8.19/LoadTestBeaconVRFConsumer.abi ../../../contracts/solc/v0.8.19/LoadTestBeaconVRFConsumer.bin 7306576bc1db6c0a4f0a8a83dd4c08e3078afa73b72858f7d1eaa410d1128fd2
-vrf_beacon: ../../../contracts/solc/v0.8.19/VRFBeacon.abi ../../../contracts/solc/v0.8.19/VRFBeacon.bin 63107992adf02024afccbe77fdf973777548dcd4d9af1484c8449aca6de30f4c
-vrf_beacon_consumer: ../../../contracts/solc/v0.8.19/BeaconVRFConsumer.abi ../../../contracts/solc/v0.8.19/BeaconVRFConsumer.bin 520f1c24e4d926a4eb6c9504506b55b79a35ae8cc65ee02d28309a7d5b735a53
-vrf_beacon_coordinator: ../../../contracts/solc/v0.8.15/VRFBeaconCoordinator.abi ../../../contracts/solc/v0.8.15/VRFBeaconCoordinator.bin 08da747a3488fcd318ddc0db75fd0df7c07a100b2e19061f0efcb12a7180ecde
-vrf_coordinator: ../../../contracts/solc/v0.8.19/VRFCoordinator.abi ../../../contracts/solc/v0.8.19/VRFCoordinator.bin 295bec795ab8c1ef08b6b27a67bab7f06233660e8a2f389211e470cc2b58c5ea
diff --git a/core/gethwrappers/ocr2vrf/go_generate.go b/core/gethwrappers/ocr2vrf/go_generate.go
deleted file mode 100644
index 475bf7e8f67..00000000000
--- a/core/gethwrappers/ocr2vrf/go_generate.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Package gethwrappers provides tools for wrapping solidity contracts with
-// golang packages, using abigen.
-package gethwrappers
-
-// OCR2VRF - remove the _disabled tag to run these locally.
-//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DKG.abi ../../../contracts/solc/v0.8.19/DKG.bin DKG dkg
-//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/VRFCoordinator.abi ../../../contracts/solc/v0.8.19/VRFCoordinator.bin VRFCoordinator vrf_coordinator
-//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/VRFBeacon.abi ../../../contracts/solc/v0.8.19/VRFBeacon.bin VRFBeacon vrf_beacon
-//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/BeaconVRFConsumer.abi ../../../contracts/solc/v0.8.19/BeaconVRFConsumer.bin BeaconVRFConsumer vrf_beacon_consumer
-//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/LoadTestBeaconVRFConsumer.abi ../../../contracts/solc/v0.8.19/LoadTestBeaconVRFConsumer.bin LoadTestBeaconVRFConsumer load_test_beacon_consumer
diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go
index 48acbd69bb3..ba182d60515 100644
--- a/core/internal/cltest/cltest.go
+++ b/core/internal/cltest/cltest.go
@@ -182,8 +182,8 @@ type JobPipelineConfig interface {
func NewJobPipelineV2(t testing.TB, cfg pipeline.BridgeConfig, jpcfg JobPipelineConfig, dbCfg pg.QConfig, legacyChains legacyevm.LegacyChainContainer, db *sqlx.DB, keyStore keystore.Master, restrictedHTTPClient, unrestrictedHTTPClient *http.Client) JobPipelineV2TestHelper {
lggr := logger.TestLogger(t)
- prm := pipeline.NewORM(db, lggr, dbCfg, jpcfg.MaxSuccessfulRuns())
- btORM := bridges.NewORM(db, lggr, dbCfg)
+ prm := pipeline.NewORM(db, lggr, jpcfg.MaxSuccessfulRuns())
+ btORM := bridges.NewORM(db)
jrm := job.NewORM(db, prm, btORM, keyStore, lggr, dbCfg)
pr := pipeline.NewRunner(prm, btORM, jpcfg, cfg, legacyChains, keyStore.Eth(), keyStore.VRF(), lggr, restrictedHTTPClient, unrestrictedHTTPClient)
return JobPipelineV2TestHelper{
@@ -588,6 +588,7 @@ type User struct {
func (ta *TestApplication) NewHTTPClient(user *User) HTTPClientCleaner {
ta.t.Helper()
+ ctx := testutils.Context(ta.t)
if user == nil {
user = &User{}
@@ -604,7 +605,7 @@ func (ta *TestApplication) NewHTTPClient(user *User) HTTPClientCleaner {
u, err := clsessions.NewUser(user.Email, Password, user.Role)
require.NoError(ta.t, err)
- err = ta.BasicAdminUsersORM().CreateUser(&u)
+ err = ta.BasicAdminUsersORM().CreateUser(ctx, &u)
require.NoError(ta.t, err)
sessionID := ta.MustSeedNewSession(user.Email)
diff --git a/core/internal/cltest/factories.go b/core/internal/cltest/factories.go
index 2ca7b4947c5..43cf902ca8a 100644
--- a/core/internal/cltest/factories.go
+++ b/core/internal/cltest/factories.go
@@ -44,7 +44,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/keeper"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
"github.com/smartcontractkit/chainlink/v2/core/utils"
@@ -99,10 +98,10 @@ func NewBridgeType(t testing.TB, opts BridgeOpts) (*bridges.BridgeTypeAuthentica
// MustCreateBridge creates a bridge
// Be careful not to specify a name here unless you ABSOLUTELY need to
// This is because name is a unique index and identical names used across transactional tests will lock/deadlock
-func MustCreateBridge(t testing.TB, db *sqlx.DB, opts BridgeOpts, cfg pg.QConfig) (bta *bridges.BridgeTypeAuthentication, bt *bridges.BridgeType) {
+func MustCreateBridge(t testing.TB, db *sqlx.DB, opts BridgeOpts) (bta *bridges.BridgeTypeAuthentication, bt *bridges.BridgeType) {
bta, bt = NewBridgeType(t, opts)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg)
- err := orm.CreateBridgeType(bt)
+ orm := bridges.NewORM(db)
+ err := orm.CreateBridgeType(testutils.Context(t), bt)
require.NoError(t, err)
return bta, bt
}
@@ -379,15 +378,16 @@ func MakeDirectRequestJobSpec(t *testing.T) *job.Job {
return spec
}
-func MustInsertKeeperJob(t *testing.T, db *sqlx.DB, korm keeper.ORM, from evmtypes.EIP55Address, contract evmtypes.EIP55Address) job.Job {
+func MustInsertKeeperJob(t *testing.T, db *sqlx.DB, korm *keeper.ORM, from evmtypes.EIP55Address, contract evmtypes.EIP55Address) job.Job {
t.Helper()
+ ctx := testutils.Context(t)
var keeperSpec job.KeeperSpec
- err := korm.Q().Get(&keeperSpec, `INSERT INTO keeper_specs (contract_address, from_address, created_at, updated_at,evm_chain_id) VALUES ($1, $2, NOW(), NOW(), $3) RETURNING *`, contract, from, testutils.SimulatedChainID.Int64())
+ err := korm.DataSource().GetContext(ctx, &keeperSpec, `INSERT INTO keeper_specs (contract_address, from_address, created_at, updated_at,evm_chain_id) VALUES ($1, $2, NOW(), NOW(), $3) RETURNING *`, contract, from, testutils.SimulatedChainID.Int64())
require.NoError(t, err)
var pipelineSpec pipeline.Spec
- err = korm.Q().Get(&pipelineSpec, `INSERT INTO pipeline_specs (dot_dag_source,created_at) VALUES ('',NOW()) RETURNING *`)
+ err = korm.DataSource().GetContext(ctx, &pipelineSpec, `INSERT INTO pipeline_specs (dot_dag_source,created_at) VALUES ('',NOW()) RETURNING *`)
require.NoError(t, err)
jb := job.Job{
@@ -402,8 +402,8 @@ func MustInsertKeeperJob(t *testing.T, db *sqlx.DB, korm keeper.ORM, from evmtyp
cfg := configtest.NewTestGeneralConfig(t)
tlg := logger.TestLogger(t)
- prm := pipeline.NewORM(db, tlg, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- btORM := bridges.NewORM(db, tlg, cfg.Database())
+ prm := pipeline.NewORM(db, tlg, cfg.JobPipeline().MaxSuccessfulRuns())
+ btORM := bridges.NewORM(db)
jrm := job.NewORM(db, prm, btORM, nil, tlg, cfg.Database())
err = jrm.InsertJob(&jb)
require.NoError(t, err)
@@ -411,10 +411,11 @@ func MustInsertKeeperJob(t *testing.T, db *sqlx.DB, korm keeper.ORM, from evmtyp
return jb
}
-func MustInsertKeeperRegistry(t *testing.T, db *sqlx.DB, korm keeper.ORM, ethKeyStore keystore.Eth, keeperIndex, numKeepers, blockCountPerTurn int32) (keeper.Registry, job.Job) {
+func MustInsertKeeperRegistry(t *testing.T, db *sqlx.DB, korm *keeper.ORM, ethKeyStore keystore.Eth, keeperIndex, numKeepers, blockCountPerTurn int32) (keeper.Registry, job.Job) {
+ t.Helper()
+ ctx := testutils.Context(t)
key, _ := MustInsertRandomKey(t, ethKeyStore, *ubig.New(testutils.SimulatedChainID))
from := key.EIP55Address
- t.Helper()
contractAddress := NewEIP55Address()
jb := MustInsertKeeperJob(t, db, korm, from, contractAddress)
registry := keeper.Registry{
@@ -429,13 +430,14 @@ func MustInsertKeeperRegistry(t *testing.T, db *sqlx.DB, korm keeper.ORM, ethKey
from: keeperIndex,
},
}
- err := korm.UpsertRegistry(®istry)
+ err := korm.UpsertRegistry(ctx, ®istry)
require.NoError(t, err)
return registry, jb
}
-func MustInsertUpkeepForRegistry(t *testing.T, db *sqlx.DB, cfg pg.QConfig, registry keeper.Registry) keeper.UpkeepRegistration {
- korm := keeper.NewORM(db, logger.TestLogger(t), cfg)
+func MustInsertUpkeepForRegistry(t *testing.T, db *sqlx.DB, registry keeper.Registry) keeper.UpkeepRegistration {
+ ctx := testutils.Context(t)
+ korm := keeper.NewORM(db, logger.TestLogger(t))
upkeepID := ubig.NewI(int64(mathrand.Uint32()))
upkeep := keeper.UpkeepRegistration{
UpkeepID: upkeepID,
@@ -447,7 +449,7 @@ func MustInsertUpkeepForRegistry(t *testing.T, db *sqlx.DB, cfg pg.QConfig, regi
positioningConstant, err := keeper.CalcPositioningConstant(upkeepID, registry.ContractAddress)
require.NoError(t, err)
upkeep.PositioningConstant = positioningConstant
- err = korm.UpsertUpkeep(&upkeep)
+ err = korm.UpsertUpkeep(ctx, &upkeep)
require.NoError(t, err)
return upkeep
}
@@ -545,6 +547,7 @@ type ExternalInitiatorOpts struct {
}
func MustInsertExternalInitiatorWithOpts(t *testing.T, orm bridges.ORM, opts ExternalInitiatorOpts) (ei bridges.ExternalInitiator) {
+ ctx := testutils.Context(t)
var prefix string
if opts.NamePrefix != "" {
prefix = opts.NamePrefix
@@ -561,7 +564,7 @@ func MustInsertExternalInitiatorWithOpts(t *testing.T, orm bridges.ORM, opts Ext
hashedSecret, err := auth.HashedSecret(token, ei.Salt)
require.NoError(t, err)
ei.HashedSecret = hashedSecret
- err = orm.CreateExternalInitiator(&ei)
+ err = orm.CreateExternalInitiator(ctx, &ei)
require.NoError(t, err)
return ei
}
diff --git a/core/internal/cltest/job_factories.go b/core/internal/cltest/job_factories.go
index 4b2ea66f22d..2b527fbc29c 100644
--- a/core/internal/cltest/job_factories.go
+++ b/core/internal/cltest/job_factories.go
@@ -11,6 +11,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
@@ -43,12 +44,13 @@ func MinimalOCRNonBootstrapSpec(contractAddress, transmitterAddress types.EIP55A
}
func MustInsertWebhookSpec(t *testing.T, db *sqlx.DB) (job.Job, job.WebhookSpec) {
+ ctx := testutils.Context(t)
jobORM, pipelineORM := getORMs(t, db)
webhookSpec := job.WebhookSpec{}
require.NoError(t, jobORM.InsertWebhookSpec(&webhookSpec))
pSpec := pipeline.Pipeline{}
- pipelineSpecID, err := pipelineORM.CreateSpec(pSpec, 0)
+ pipelineSpecID, err := pipelineORM.CreateSpec(ctx, nil, pSpec, 0)
require.NoError(t, err)
createdJob := job.Job{WebhookSpecID: &webhookSpec.ID, WebhookSpec: &webhookSpec, SchemaVersion: 1, Type: "webhook",
@@ -62,8 +64,8 @@ func getORMs(t *testing.T, db *sqlx.DB) (jobORM job.ORM, pipelineORM pipeline.OR
config := configtest.NewTestGeneralConfig(t)
keyStore := NewKeyStore(t, db, config.Database())
lggr := logger.TestLogger(t)
- pipelineORM = pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgeORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM = pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgeORM := bridges.NewORM(db)
jobORM = job.NewORM(db, pipelineORM, bridgeORM, keyStore, lggr, config.Database())
t.Cleanup(func() { jobORM.Close() })
return
diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go
index fbfd820309a..36d10981962 100644
--- a/core/internal/cltest/mocks.go
+++ b/core/internal/cltest/mocks.go
@@ -12,6 +12,7 @@ import (
"time"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/jmoiron/sqlx"
@@ -312,10 +313,11 @@ func MustRandomUser(t testing.TB) sessions.User {
}
func NewUserWithSession(t testing.TB, orm sessions.AuthenticationProvider) sessions.User {
+ ctx := testutils.Context(t)
u := MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&u))
+ require.NoError(t, orm.CreateUser(ctx, &u))
- _, err := orm.CreateSession(sessions.SessionRequest{
+ _, err := orm.CreateSession(ctx, sessions.SessionRequest{
Email: u.Email,
Password: Password,
})
@@ -332,13 +334,13 @@ func NewMockAPIInitializer(t testing.TB) *MockAPIInitializer {
return &MockAPIInitializer{t: t}
}
-func (m *MockAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
- if user, err := orm.FindUser(APIEmailAdmin); err == nil {
+func (m *MockAPIInitializer) Initialize(ctx context.Context, orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
+ if user, err := orm.FindUser(ctx, APIEmailAdmin); err == nil {
return user, err
}
m.Count++
user := MustRandomUser(m.t)
- return user, orm.CreateUser(&user)
+ return user, orm.CreateUser(ctx, &user)
}
func NewMockAuthenticatedHTTPClient(lggr logger.Logger, cfg cmd.ClientOpts, sessionID string) cmd.HTTPClient {
diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go
index cd231450650..4afad453110 100644
--- a/core/internal/features/features_test.go
+++ b/core/internal/features/features_test.go
@@ -175,7 +175,7 @@ func TestIntegration_ExternalInitiatorV2(t *testing.T) {
require.NoError(t, err)
}))
u, _ := url.Parse(bridgeServer.URL)
- err := app.BridgeORM().CreateBridgeType(&bridges.BridgeType{
+ err := app.BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{
Name: bridges.BridgeName("substrate-adapter1"),
URL: models.WebURL(*u),
})
@@ -236,8 +236,8 @@ observationSource = """
_ = cltest.CreateJobRunViaExternalInitiatorV2(t, app, jobUUID, *eia, cltest.MustJSONMarshal(t, eiRequest))
- pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- bridgeORM := bridges.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database())
+ pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ bridgeORM := bridges.NewORM(app.GetSqlxDB())
jobORM := job.NewORM(app.GetSqlxDB(), pipelineORM, bridgeORM, app.KeyStore, logger.TestLogger(t), cfg.Database())
runs := cltest.WaitForPipelineComplete(t, 0, jobID, 1, 2, jobORM, 5*time.Second, 300*time.Millisecond)
@@ -259,6 +259,7 @@ observationSource = """
func TestIntegration_AuthToken(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
@@ -268,8 +269,8 @@ func TestIntegration_AuthToken(t *testing.T) {
key, secret := uuid.New().String(), uuid.New().String()
apiToken := auth.Token{AccessKey: key, Secret: secret}
orm := app.AuthenticationProvider()
- require.NoError(t, orm.CreateUser(&mockUser))
- require.NoError(t, orm.SetAuthToken(&mockUser, &apiToken))
+ require.NoError(t, orm.CreateUser(ctx, &mockUser))
+ require.NoError(t, orm.SetAuthToken(ctx, &mockUser, &apiToken))
url := app.Server.URL + "/users"
headers := make(map[string]string)
@@ -927,7 +928,7 @@ isBootstrapPeer = true
}))
t.Cleanup(servers[i].Close)
u, _ := url.Parse(servers[i].URL)
- err := apps[i].BridgeORM().CreateBridgeType(&bridges.BridgeType{
+ err := apps[i].BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{
Name: bridges.BridgeName(fmt.Sprintf("bridge%d", i)),
URL: models.WebURL(*u),
})
@@ -1153,7 +1154,7 @@ isBootstrapPeer = true
}))
t.Cleanup(servers[i].Close)
u, _ := url.Parse(servers[i].URL)
- err := apps[i].BridgeORM().CreateBridgeType(&bridges.BridgeType{
+ err := apps[i].BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{
Name: bridges.BridgeName(fmt.Sprintf("bridge%d", i)),
URL: models.WebURL(*u),
})
diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go
index 1273608a203..06f57c805ec 100644
--- a/core/internal/features/ocr2/features_ocr2_test.go
+++ b/core/internal/features/ocr2/features_ocr2_test.go
@@ -308,7 +308,7 @@ fromBlock = %d
}))
t.Cleanup(servers[s].Close)
u, _ := url.Parse(servers[i].URL)
- require.NoError(t, apps[i].BridgeORM().CreateBridgeType(&bridges.BridgeType{
+ require.NoError(t, apps[i].BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{
Name: bridges.BridgeName(fmt.Sprintf("bridge%d", i)),
URL: models.WebURL(*u),
}))
@@ -789,7 +789,7 @@ chainID = 1337
servers[s].Close()
})
u, _ := url.Parse(servers[i].URL)
- require.NoError(t, apps[i].BridgeORM().CreateBridgeType(&bridges.BridgeType{
+ require.NoError(t, apps[i].BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{
Name: bridges.BridgeName(fmt.Sprintf("bridge%d", i)),
URL: models.WebURL(*u),
}))
diff --git a/core/internal/mocks/go_generate.go b/core/internal/mocks/go_generate.go
index f3f5f0ae2ca..8402f71158d 100644
--- a/core/internal/mocks/go_generate.go
+++ b/core/internal/mocks/go_generate.go
@@ -4,5 +4,5 @@ package mocks
//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flags_wrapper --name FlagsInterface --output . --case=underscore --structname Flags --filename flags.go
//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface --name AggregatorV3InterfaceInterface --output ../../services/vrf/mocks/ --case=underscore --structname AggregatorV3Interface --filename aggregator_v3_interface.go
//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2 --name VRFCoordinatorV2Interface --output ../../services/vrf/mocks/ --case=underscore --structname VRFCoordinatorV2Interface --filename vrf_coordinator_v2.go
-//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon --name VRFBeaconInterface --output ../../services/ocr2/plugins/ocr2vrf/coordinator/mocks --case=underscore --structname VRFBeaconInterface --filename vrf_beacon.go
-//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator --name VRFCoordinatorInterface --output ../../services/ocr2/plugins/ocr2vrf/coordinator/mocks --case=underscore --structname VRFCoordinatorInterface --filename vrf_coordinator.go
+//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon --name VRFBeaconInterface --output ../../services/ocr2/plugins/ocr2vrf/coordinator/mocks --case=underscore --structname VRFBeaconInterface --filename vrf_beacon.go
+//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator --name VRFCoordinatorInterface --output ../../services/ocr2/plugins/ocr2vrf/coordinator/mocks --case=underscore --structname VRFCoordinatorInterface --filename vrf_coordinator.go
diff --git a/core/internal/testutils/pgtest/txdb.go b/core/internal/testutils/pgtest/txdb.go
index da9fd6cb2d0..38fe8390bab 100644
--- a/core/internal/testutils/pgtest/txdb.go
+++ b/core/internal/testutils/pgtest/txdb.go
@@ -19,6 +19,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/store/dialects"
)
+// TODO still need to import this for side effects
// txdb is a simplified version of https://github.com/DATA-DOG/go-txdb
//
// The original lib has various problems and is hard to understand because it
diff --git a/core/scripts/go.mod b/core/scripts/go.mod
index 2176664f561..c7cd3a72d75 100644
--- a/core/scripts/go.mod
+++ b/core/scripts/go.mod
@@ -10,7 +10,7 @@ require (
github.com/docker/go-connections v0.4.0
github.com/ethereum/go-ethereum v1.13.8
github.com/google/go-cmp v0.6.0
- github.com/google/uuid v1.4.0
+ github.com/google/uuid v1.5.0
github.com/jmoiron/sqlx v1.3.5
github.com/joho/godotenv v1.4.0
github.com/jonboulle/clockwork v0.4.0
@@ -20,9 +20,9 @@ require (
github.com/pelletier/go-toml/v2 v2.1.1
github.com/prometheus/client_golang v1.17.0
github.com/shopspring/decimal v1.3.1
- github.com/smartcontractkit/chainlink-automation v1.0.2
- github.com/smartcontractkit/chainlink-common v0.1.7-0.20240405173118-f5bf144ec6b3
- github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868
+ github.com/smartcontractkit/chainlink-automation v1.0.3
+ github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e
+ github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772
github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000
github.com/smartcontractkit/libocr v0.0.0-20240326191951-2bbe9382d052
github.com/spf13/cobra v1.6.1
@@ -249,6 +249,7 @@ require (
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
+ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/scylladb/go-reflectx v1.0.1 // indirect
github.com/sethvargo/go-retry v0.2.4 // indirect
@@ -263,7 +264,7 @@ require (
github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 // indirect
github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect
github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect
- github.com/smartcontractkit/wsrpc v0.7.2 // indirect
+ github.com/smartcontractkit/wsrpc v0.8.1 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
diff --git a/core/scripts/go.sum b/core/scripts/go.sum
index 5d74d23da68..22bde9d5929 100644
--- a/core/scripts/go.sum
+++ b/core/scripts/go.sum
@@ -161,7 +161,6 @@ github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
-github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -638,10 +637,9 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
-github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
+github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ=
github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
@@ -1185,10 +1183,10 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCqR1LNS7aI3jT0V+xGrg=
github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
-github.com/smartcontractkit/chainlink-automation v1.0.2 h1:xsfyuswL15q2YBGQT3qn2SBz6fnSKiSW7XZ8IZQLpnI=
-github.com/smartcontractkit/chainlink-automation v1.0.2/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU=
-github.com/smartcontractkit/chainlink-common v0.1.7-0.20240405173118-f5bf144ec6b3 h1:LCVHf/ooB4HDkgfLUq+jK4CuCr6SsdNCQZt3/etJ8ms=
-github.com/smartcontractkit/chainlink-common v0.1.7-0.20240405173118-f5bf144ec6b3/go.mod h1:kstYjAGqBswdZpl7YkSPeXBDVwaY1VaR6tUMPWl8ykA=
+github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs=
+github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU=
+github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e h1:nHs5mFOR7FPII20GrCGIPywDW43MhEUlD7DqHnTgu6Q=
+github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg=
github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc=
github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo=
@@ -1199,8 +1197,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19
github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw=
github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw=
github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg=
-github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8=
-github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs=
+github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1:LQmRsrzzaYYN3wEU1l5tWiccznhvbyGnu2N+wHSXZAo=
+github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs=
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=
@@ -1211,8 +1209,8 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-
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=
github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw=
-github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ=
-github.com/smartcontractkit/wsrpc v0.7.2/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0=
+github.com/smartcontractkit/wsrpc v0.8.1 h1:kk0SXLqWrWaZ3J6c7n8D0NZ2uTMBBBpG5dZZXZX8UGE=
+github.com/smartcontractkit/wsrpc v0.8.1/go.mod h1:yfg8v8fPLXkb6Mcnx6Pm/snP6jJ0r5Kf762Yd1a/KpA=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -1420,7 +1418,6 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
-go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -1438,7 +1435,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
-go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
@@ -1780,7 +1776,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-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.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
diff --git a/core/scripts/ocr2vrf/util.go b/core/scripts/ocr2vrf/util.go
index e57f349f1fd..a11c799d9a3 100644
--- a/core/scripts/ocr2vrf/util.go
+++ b/core/scripts/ocr2vrf/util.go
@@ -27,15 +27,15 @@ import (
"github.com/smartcontractkit/chainlink-vrf/ocr2vrf"
ocr2vrftypes "github.com/smartcontractkit/chainlink-vrf/types"
+ dkgContract "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/load_test_beacon_consumer"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon_consumer"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
"github.com/smartcontractkit/chainlink/v2/core/cmd"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface"
- dkgContract "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
helpers "github.com/smartcontractkit/chainlink/core/scripts/common"
)
diff --git a/core/scripts/ocr2vrf/verify.go b/core/scripts/ocr2vrf/verify.go
index 7d7fb94496a..36ecda83b5a 100644
--- a/core/scripts/ocr2vrf/verify.go
+++ b/core/scripts/ocr2vrf/verify.go
@@ -16,10 +16,10 @@ import (
"github.com/smartcontractkit/chainlink-vrf/altbn_128"
ocr2vrftypes "github.com/smartcontractkit/chainlink-vrf/types"
+ dkgContract "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
helpers "github.com/smartcontractkit/chainlink/core/scripts/common"
- dkgContract "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
)
func getDKGLatestConfigDetails(e helpers.Environment, dkgAddress string) dkgContract.LatestConfigDetails {
diff --git a/core/scripts/vrfv2plus/testnet/main.go b/core/scripts/vrfv2plus/testnet/main.go
index 49be23f1e34..45ef7314bee 100644
--- a/core/scripts/vrfv2plus/testnet/main.go
+++ b/core/scripts/vrfv2plus/testnet/main.go
@@ -1190,6 +1190,7 @@ func main() {
wrapperAddress := cmd.String("wrapper-address", "", "address of the VRFV2Wrapper contract")
wrapperGasOverhead := cmd.Uint("wrapper-gas-overhead", 50_000, "amount of gas overhead in wrapper fulfillment")
coordinatorGasOverhead := cmd.Uint("coordinator-gas-overhead", 52_000, "amount of gas overhead in coordinator fulfillment")
+ coordinatorGasOverheadPerWord := cmd.Uint("coordinator-gas-overhead-per-word", 0, "amount of gas overhead in coordinator fulfillment")
wrapperNativePremiumPercentage := cmd.Uint("wrapper-native-premium-percentage", 25, "gas premium charged by wrapper for native payment")
wrapperLinkPremiumPercentage := cmd.Uint("wrapper-link-premium-percentage", 25, "gas premium charged by wrapper for link payment")
keyHash := cmd.String("key-hash", "", "the keyhash that wrapper requests should use")
@@ -1204,6 +1205,7 @@ func main() {
common.HexToAddress(*wrapperAddress),
*wrapperGasOverhead,
*coordinatorGasOverhead,
+ *coordinatorGasOverheadPerWord,
*wrapperNativePremiumPercentage,
*wrapperLinkPremiumPercentage,
*keyHash,
diff --git a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go
index b792bca10d9..831b258fb6e 100644
--- a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go
+++ b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go
@@ -870,6 +870,7 @@ func DeployWrapperUniverse(e helpers.Environment) {
subscriptionID := cmd.String("subscription-id", "", "subscription ID for the wrapper")
wrapperGasOverhead := cmd.Uint("wrapper-gas-overhead", 50_000, "amount of gas overhead in wrapper fulfillment")
coordinatorGasOverhead := cmd.Uint("coordinator-gas-overhead", 52_000, "amount of gas overhead in coordinator fulfillment")
+ coordinatorGasOverheadPerWord := cmd.Uint("coordinator-gas-overhead-per-word", 0, "amount of gas overhead per word in coordinator fulfillment")
wrapperNativePremiumPercentage := cmd.Uint("wrapper-native-premium-percentage", 25, "gas premium charged by wrapper for native payment")
wrapperLinkPremiumPercentage := cmd.Uint("wrapper-link-premium-percentage", 25, "gas premium charged by wrapper for link payment")
keyHash := cmd.String("key-hash", "", "the keyhash that wrapper requests should use")
@@ -899,6 +900,7 @@ func DeployWrapperUniverse(e helpers.Environment) {
wrapper,
*wrapperGasOverhead,
*coordinatorGasOverhead,
+ *coordinatorGasOverheadPerWord,
*wrapperNativePremiumPercentage,
*wrapperLinkPremiumPercentage,
*keyHash,
diff --git a/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go b/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go
index d18a53dd584..8becb31239c 100644
--- a/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go
+++ b/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go
@@ -218,7 +218,8 @@ func WrapperDeploy(
func WrapperConfigure(
e helpers.Environment,
wrapperAddress common.Address,
- wrapperGasOverhead, coordinatorGasOverhead uint,
+ wrapperGasOverhead uint,
+ coordinatorGasOverhead, coordinatorGasOverheadPerWord uint,
nativePremiumPercentage, linkPremiumPercentage uint,
keyHash string,
maxNumWords uint,
@@ -234,6 +235,7 @@ func WrapperConfigure(
e.Owner,
uint32(wrapperGasOverhead),
uint32(coordinatorGasOverhead),
+ uint16(coordinatorGasOverheadPerWord),
uint8(nativePremiumPercentage),
uint8(linkPremiumPercentage),
common.HexToHash(keyHash),
diff --git a/core/services/blockhashstore/bhs.go b/core/services/blockhashstore/bhs.go
index d4dd52c5661..4d1fe761c88 100644
--- a/core/services/blockhashstore/bhs.go
+++ b/core/services/blockhashstore/bhs.go
@@ -104,7 +104,7 @@ func (c *BulletproofBHS) Store(ctx context.Context, blockNum uint64) error {
// Set a queue size of 256. At most we store the blockhash of every block, and only the
// latest 256 can possibly be stored.
- Strategy: txmgrcommon.NewQueueingTxStrategy(c.jobID, 256, c.dbConfig.DefaultQueryTimeout()),
+ Strategy: txmgrcommon.NewQueueingTxStrategy(c.jobID, 256),
})
if err != nil {
return errors.Wrap(err, "creating transaction")
diff --git a/core/services/blockhashstore/delegate.go b/core/services/blockhashstore/delegate.go
index 9a11c057c32..243259a2b1a 100644
--- a/core/services/blockhashstore/delegate.go
+++ b/core/services/blockhashstore/delegate.go
@@ -2,6 +2,7 @@ package blockhashstore
import (
"context"
+ "encoding/json"
"fmt"
"sync"
"time"
@@ -19,7 +20,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -56,6 +56,11 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi
return nil, errors.Errorf(
"blockhashstore.Delegate expects a BlockhashStoreSpec to be present, got %+v", jb)
}
+ marshalledJob, err := json.MarshalIndent(jb.BlockhashStoreSpec, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ d.logger.Debugw("Creating services for job spec", "job", string(marshalledJob))
chain, err := d.legacyChains.Get(jb.BlockhashStoreSpec.EVMChainID.String())
if err != nil {
@@ -194,7 +199,7 @@ func (d *Delegate) BeforeJobCreated(spec job.Job) {}
func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
// OnDeleteJob satisfies the job.Delegate interface.
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// service is a job.Service that runs the BHS feeder every pollPeriod.
type service struct {
diff --git a/core/services/blockheaderfeeder/delegate.go b/core/services/blockheaderfeeder/delegate.go
index 19edb43bc23..b750b735de8 100644
--- a/core/services/blockheaderfeeder/delegate.go
+++ b/core/services/blockheaderfeeder/delegate.go
@@ -2,6 +2,7 @@ package blockheaderfeeder
import (
"context"
+ "encoding/json"
"fmt"
"time"
@@ -19,7 +20,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/blockhashstore"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -53,6 +53,11 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi
if jb.BlockHeaderFeederSpec == nil {
return nil, errors.Errorf("Delegate expects a BlockHeaderFeederSpec to be present, got %+v", jb)
}
+ marshalledJob, err := json.MarshalIndent(jb.BlockHeaderFeederSpec, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ d.logger.Debugw("Creating services for job spec", "job", string(marshalledJob))
chain, err := d.legacyChains.Get(jb.BlockHeaderFeederSpec.EVMChainID.String())
if err != nil {
@@ -208,7 +213,7 @@ func (d *Delegate) BeforeJobCreated(spec job.Job) {}
func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
// OnDeleteJob satisfies the job.Delegate interface.
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// service is a job.Service that runs the BHS feeder every pollPeriod.
type service struct {
diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go
index d4a9cb5c907..176fcaa225f 100644
--- a/core/services/chainlink/application.go
+++ b/core/services/chainlink/application.go
@@ -289,7 +289,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
// Initialize Local Users ORM and Authentication Provider specified in config
// BasicAdminUsersORM is initialized and required regardless of separate Authentication Provider
- localAdminUsersORM := localauth.NewORM(sqlxDB, cfg.WebServer().SessionTimeout().Duration(), globalLogger, cfg.Database(), auditLogger)
+ localAdminUsersORM := localauth.NewORM(opts.DB, cfg.WebServer().SessionTimeout().Duration(), globalLogger, auditLogger)
// Initialize Sessions ORM based on environment configured authenticator
// localDB auth or remote LDAP auth
@@ -301,26 +301,26 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
case sessions.LDAPAuth:
var err error
authenticationProvider, err = ldapauth.NewLDAPAuthenticator(
- sqlxDB, cfg.Database(), cfg.WebServer().LDAP(), cfg.Insecure().DevWebServer(), globalLogger, auditLogger,
+ opts.DB, cfg.WebServer().LDAP(), cfg.Insecure().DevWebServer(), globalLogger, auditLogger,
)
if err != nil {
return nil, errors.Wrap(err, "NewApplication: failed to initialize LDAP Authentication module")
}
sessionReaper = ldapauth.NewLDAPServerStateSync(sqlxDB, cfg.Database(), cfg.WebServer().LDAP(), globalLogger)
case sessions.LocalAuth:
- authenticationProvider = localauth.NewORM(sqlxDB, cfg.WebServer().SessionTimeout().Duration(), globalLogger, cfg.Database(), auditLogger)
+ authenticationProvider = localauth.NewORM(opts.DB, cfg.WebServer().SessionTimeout().Duration(), globalLogger, auditLogger)
sessionReaper = localauth.NewSessionReaper(sqlxDB.DB, cfg.WebServer(), globalLogger)
default:
return nil, errors.Errorf("NewApplication: Unexpected 'AuthenticationMethod': %s supported values: %s, %s", authMethod, sessions.LocalAuth, sessions.LDAPAuth)
}
var (
- pipelineORM = pipeline.NewORM(sqlxDB, globalLogger, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- bridgeORM = bridges.NewORM(sqlxDB, globalLogger, cfg.Database())
- mercuryORM = mercury.NewORM(sqlxDB, globalLogger, cfg.Database())
+ pipelineORM = pipeline.NewORM(sqlxDB, globalLogger, cfg.JobPipeline().MaxSuccessfulRuns())
+ bridgeORM = bridges.NewORM(sqlxDB)
+ mercuryORM = mercury.NewORM(opts.DB)
pipelineRunner = pipeline.NewRunner(pipelineORM, bridgeORM, cfg.JobPipeline(), cfg.WebServer(), legacyEVMChains, keyStore.Eth(), keyStore.VRF(), globalLogger, restrictedHTTPClient, unrestrictedHTTPClient)
jobORM = job.NewORM(sqlxDB, pipelineORM, bridgeORM, keyStore, globalLogger, cfg.Database())
- txmORM = txmgr.NewTxStore(sqlxDB, globalLogger)
+ txmORM = txmgr.NewTxStore(opts.DB, globalLogger)
streamRegistry = streams.NewRegistry(globalLogger, pipelineRunner)
)
@@ -353,7 +353,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
pipelineORM,
legacyEVMChains,
globalLogger,
- cfg.Database(),
mailMon),
job.Webhook: webhook.NewDelegate(
pipelineRunner,
@@ -444,6 +443,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
delegates[job.OffchainReporting2] = ocr2.NewDelegate(
sqlxDB,
+ opts.DB,
jobORM,
bridgeORM,
mercuryORM,
@@ -835,7 +835,7 @@ func (app *ChainlinkApplication) ResumeJobV2(
taskID uuid.UUID,
result pipeline.Result,
) error {
- return app.pipelineRunner.ResumeRun(taskID, result.Value, result.Error)
+ return app.pipelineRunner.ResumeRun(ctx, taskID, result.Value, result.Error)
}
func (app *ChainlinkApplication) GetFeedsService() feeds.Service {
diff --git a/core/services/cron/cron_test.go b/core/services/cron/cron_test.go
index 5c968c75824..c3ecc0957c7 100644
--- a/core/services/cron/cron_test.go
+++ b/core/services/cron/cron_test.go
@@ -27,8 +27,8 @@ func TestCronV2Pipeline(t *testing.T) {
keyStore := cltest.NewKeyStore(t, db, cfg.Database())
lggr := logger.TestLogger(t)
- orm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- btORM := bridges.NewORM(db, lggr, cfg.Database())
+ orm := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns())
+ btORM := bridges.NewORM(db)
jobORM := job.NewORM(db, orm, btORM, keyStore, lggr, cfg.Database())
jb := &job.Job{
diff --git a/core/services/cron/delegate.go b/core/services/cron/delegate.go
index 05b5b36c00f..d8a1390103e 100644
--- a/core/services/cron/delegate.go
+++ b/core/services/cron/delegate.go
@@ -7,7 +7,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
)
@@ -29,10 +28,10 @@ func (d *Delegate) JobType() job.Type {
return job.Cron
}
-func (d *Delegate) BeforeJobCreated(spec job.Job) {}
-func (d *Delegate) AfterJobCreated(spec job.Job) {}
-func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) BeforeJobCreated(spec job.Job) {}
+func (d *Delegate) AfterJobCreated(spec job.Job) {}
+func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec returns the scheduler to be used for running cron jobs
func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services []job.ServiceCtx, err error) {
diff --git a/core/services/directrequest/delegate.go b/core/services/directrequest/delegate.go
index d6afc215fb9..33a0a7e73da 100644
--- a/core/services/directrequest/delegate.go
+++ b/core/services/directrequest/delegate.go
@@ -11,6 +11,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/assets"
"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/log"
@@ -19,7 +20,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_wrapper"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
)
@@ -63,10 +63,10 @@ func (d *Delegate) JobType() job.Type {
return job.DirectRequest
}
-func (d *Delegate) BeforeJobCreated(spec job.Job) {}
-func (d *Delegate) AfterJobCreated(spec job.Job) {}
-func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) BeforeJobCreated(spec job.Job) {}
+func (d *Delegate) AfterJobCreated(spec job.Job) {}
+func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec returns the log listener service for a direct request job
func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.ServiceCtx, error) {
@@ -191,7 +191,7 @@ func (l *listener) Close() error {
})
}
-func (l *listener) HandleLog(lb log.Broadcast) {
+func (l *listener) HandleLog(ctx context.Context, lb log.Broadcast) {
log := lb.DecodedLog()
if log == nil || reflect.ValueOf(log).IsNil() {
l.logger.Error("HandleLog: ignoring nil value")
@@ -374,7 +374,7 @@ func (l *listener) handleOracleRequest(ctx context.Context, request *operator_wr
},
})
run := pipeline.NewRun(*l.job.PipelineSpec, vars)
- _, err := l.pipelineRunner.Run(ctx, run, l.logger, true, func(tx pg.Queryer) error {
+ _, err := l.pipelineRunner.Run(ctx, run, l.logger, true, func(tx sqlutil.DataSource) error {
l.markLogConsumed(ctx, lb)
return nil
})
@@ -407,7 +407,7 @@ func (l *listener) handleCancelOracleRequest(ctx context.Context, request *opera
}
func (l *listener) markLogConsumed(ctx context.Context, lb log.Broadcast) {
- if err := l.logBroadcaster.MarkConsumed(ctx, lb); err != nil {
+ if err := l.logBroadcaster.MarkConsumed(ctx, nil, lb); err != nil {
l.logger.Errorw("Unable to mark log consumed", "err", err, "log", lb.String())
}
}
diff --git a/core/services/directrequest/delegate_test.go b/core/services/directrequest/delegate_test.go
index d8540b4471c..0235a0c4eec 100644
--- a/core/services/directrequest/delegate_test.go
+++ b/core/services/directrequest/delegate_test.go
@@ -15,6 +15,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/assets"
"github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox/mailboxtest"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
@@ -31,7 +32,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/services/directrequest"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
pipeline_mocks "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
@@ -88,8 +88,8 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi
keyStore := cltest.NewKeyStore(t, db, cfg.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, LogBroadcaster: broadcaster, MailMon: mailMon, KeyStore: keyStore.Eth()})
lggr := logger.TestLogger(t)
- orm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- btORM := bridges.NewORM(db, lggr, cfg.Database())
+ orm := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns())
+ btORM := bridges.NewORM(db)
jobORM := job.NewORM(db, orm, btORM, keyStore, lggr, cfg.Database())
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
delegate := directrequest.NewDelegate(lggr, runner, orm, legacyChains, mailMon)
@@ -159,28 +159,29 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
})
log.On("DecodedLog").Return(&logOracleRequest)
log.On("String").Return("")
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
runBeganAwaiter := cltest.NewAwaiter()
uni.runner.On("Run", mock.Anything, mock.AnythingOfType("*pipeline.Run"), mock.Anything, mock.Anything, mock.Anything).
Return(false, nil).
Run(func(args mock.Arguments) {
runBeganAwaiter.ItHappened()
- fn := args.Get(4).(func(pg.Queryer) error)
+ fn := args.Get(4).(func(source sqlutil.DataSource) error)
require.NoError(t, fn(nil))
}).Once()
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
require.NotNil(t, uni.listener, "listener was nil; expected broadcaster.Register to have been called")
// check if the job exists under the correct ID
- drJob, jErr := uni.jobORM.FindJob(testutils.Context(t), uni.listener.JobID())
+ drJob, jErr := uni.jobORM.FindJob(ctx, uni.listener.JobID())
require.NoError(t, jErr)
require.Equal(t, drJob.ID, uni.listener.JobID())
require.NotNil(t, drJob.DirectRequestSpec)
- uni.listener.HandleLog(log)
+ uni.listener.HandleLog(ctx, log)
runBeganAwaiter.AwaitOrFail(t, 5*time.Second)
@@ -207,12 +208,13 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log.On("DecodedLog").Return(&logOracleRequest).Maybe()
log.On("String").Return("")
log.On("EVMChainID").Return(*big.NewInt(0))
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil).Maybe()
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil).Maybe()
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
- uni.listener.HandleLog(log)
+ uni.listener.HandleLog(ctx, log)
uni.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
@@ -224,7 +226,7 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
uni.runner.On("Run", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Run(func(args mock.Arguments) {
runBeganAwaiter.ItHappened()
- fn := args.Get(4).(func(pg.Queryer) error)
+ fn := args.Get(4).(func(sqlutil.DataSource) error)
require.NoError(t, fn(nil))
}).Once().Return(false, nil)
@@ -241,7 +243,7 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log := log_mocks.NewBroadcast(t)
lbAwaiter := cltest.NewAwaiter()
uni.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { lbAwaiter.ItHappened() }).Return(nil)
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { lbAwaiter.ItHappened() }).Return(nil)
logCancelOracleRequest := operator_wrapper.OperatorCancelOracleRequest{RequestId: uni.spec.ExternalIDEncodeStringToTopic()}
logAwaiter := cltest.NewAwaiter()
@@ -251,10 +253,11 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
})
log.On("String").Return("")
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
- uni.listener.HandleLog(log)
+ uni.listener.HandleLog(ctx, log)
logAwaiter.AwaitOrFail(t)
lbAwaiter.AwaitOrFail(t)
@@ -279,12 +282,13 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log.On("String").Return("")
log.On("DecodedLog").Return(&logCancelOracleRequest)
lbAwaiter := cltest.NewAwaiter()
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { lbAwaiter.ItHappened() }).Return(nil)
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { lbAwaiter.ItHappened() }).Return(nil)
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
- uni.listener.HandleLog(log)
+ uni.listener.HandleLog(ctx, log)
lbAwaiter.AwaitOrFail(t)
@@ -314,7 +318,7 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
})
runLog.On("DecodedLog").Return(&logOracleRequest)
runLog.On("String").Return("")
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
cancelLog := log_mocks.NewBroadcast(t)
@@ -328,9 +332,10 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
})
cancelLog.On("DecodedLog").Return(&logCancelOracleRequest)
cancelLog.On("String").Return("")
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
timeout := 5 * time.Second
@@ -346,11 +351,11 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
runCancelledAwaiter.ItHappened()
}
}).Once().Return(false, nil)
- uni.listener.HandleLog(runLog)
+ uni.listener.HandleLog(ctx, runLog)
runBeganAwaiter.AwaitOrFail(t, timeout)
- uni.listener.HandleLog(cancelLog)
+ uni.listener.HandleLog(ctx, cancelLog)
runCancelledAwaiter.AwaitOrFail(t, timeout)
@@ -384,25 +389,26 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
})
log.On("DecodedLog").Return(&logOracleRequest)
log.On("String").Return("")
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
runBeganAwaiter := cltest.NewAwaiter()
uni.runner.On("Run", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
runBeganAwaiter.ItHappened()
- fn := args.Get(4).(func(pg.Queryer) error)
+ fn := args.Get(4).(func(sqlutil.DataSource) error)
require.NoError(t, fn(nil))
}).Once().Return(false, nil)
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
// check if the job exists under the correct ID
- drJob, jErr := uni.jobORM.FindJob(testutils.Context(t), uni.listener.JobID())
+ drJob, jErr := uni.jobORM.FindJob(ctx, uni.listener.JobID())
require.NoError(t, jErr)
require.Equal(t, drJob.ID, uni.listener.JobID())
require.NotNil(t, drJob.DirectRequestSpec)
- uni.listener.HandleLog(log)
+ uni.listener.HandleLog(ctx, log)
runBeganAwaiter.AwaitOrFail(t, 5*time.Second)
@@ -433,14 +439,15 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log.On("DecodedLog").Return(&logOracleRequest)
log.On("String").Return("")
markConsumedLogAwaiter := cltest.NewAwaiter()
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
markConsumedLogAwaiter.ItHappened()
}).Return(nil)
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
- uni.listener.HandleLog(log)
+ uni.listener.HandleLog(ctx, log)
markConsumedLogAwaiter.AwaitOrFail(t, 5*time.Second)
@@ -479,27 +486,28 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log.On("DecodedLog").Return(&logOracleRequest)
log.On("String").Return("")
markConsumedLogAwaiter := cltest.NewAwaiter()
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
markConsumedLogAwaiter.ItHappened()
}).Return(nil)
runBeganAwaiter := cltest.NewAwaiter()
uni.runner.On("Run", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
runBeganAwaiter.ItHappened()
- fn := args.Get(4).(func(pg.Queryer) error)
+ fn := args.Get(4).(func(sqlutil.DataSource) error)
require.NoError(t, fn(nil))
}).Once().Return(false, nil)
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
// check if the job exists under the correct ID
- drJob, jErr := uni.jobORM.FindJob(testutils.Context(t), uni.listener.JobID())
+ drJob, jErr := uni.jobORM.FindJob(ctx, uni.listener.JobID())
require.NoError(t, jErr)
require.Equal(t, drJob.ID, uni.listener.JobID())
require.NotNil(t, drJob.DirectRequestSpec)
- uni.listener.HandleLog(log)
+ uni.listener.HandleLog(ctx, log)
runBeganAwaiter.AwaitOrFail(t, 5*time.Second)
@@ -534,14 +542,15 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log.On("DecodedLog").Return(&logOracleRequest)
log.On("String").Return("")
markConsumedLogAwaiter := cltest.NewAwaiter()
- uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
markConsumedLogAwaiter.ItHappened()
}).Return(nil)
- err := uni.service.Start(testutils.Context(t))
+ ctx := testutils.Context(t)
+ err := uni.service.Start(ctx)
require.NoError(t, err)
- uni.listener.HandleLog(log)
+ uni.listener.HandleLog(ctx, log)
markConsumedLogAwaiter.AwaitOrFail(t, 5*time.Second)
diff --git a/core/services/feeds/orm_test.go b/core/services/feeds/orm_test.go
index 78af9bf6912..51a85a33a46 100644
--- a/core/services/feeds/orm_test.go
+++ b/core/services/feeds/orm_test.go
@@ -1652,8 +1652,8 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job {
config = configtest.NewGeneralConfig(t, nil)
keyStore = cltest.NewKeyStore(t, db, config.Database())
lggr = logger.TestLogger(t)
- pipelineORM = pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgeORM = bridges.NewORM(db, lggr, config.Database())
+ pipelineORM = pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgeORM = bridges.NewORM(db)
relayExtenders = evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
)
orm := job.NewORM(db, pipelineORM, bridgeORM, keyStore, lggr, config.Database())
@@ -1662,8 +1662,8 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job {
defer func() { assert.NoError(t, orm.Close()) }()
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go
index 2f3b309b45c..27d324d2342 100644
--- a/core/services/feeds/service.go
+++ b/core/services/feeds/service.go
@@ -732,7 +732,7 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error {
}
// Check that the bridges exist
- if err = s.jobORM.AssertBridgesExist(j.Pipeline); err != nil {
+ if err = s.jobORM.AssertBridgesExist(ctx, j.Pipeline); err != nil {
logger.Errorw("Failed to approve job spec due to bridge check", "err", err.Error())
return errors.Wrap(err, "failed to approve job spec due to bridge check")
@@ -1191,7 +1191,7 @@ func (s *service) newChainConfigMsg(cfg ChainConfig) (*pb.ChainConfig, error) {
}, nil
}
-// newFMConfigMsg generates a FMConfig protobuf message. Flux Monitor does not
+// newFluxMonitorConfigMsg generates a FMConfig protobuf message. Flux Monitor does not
// have any configuration but this is here for consistency.
func (*service) newFluxMonitorConfigMsg(cfg FluxMonitorConfig) *pb.FluxMonitorConfig {
return &pb.FluxMonitorConfig{Enabled: cfg.Enabled}
diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go
index dcb57e5fd3c..0dc07b57d43 100644
--- a/core/services/feeds/service_test.go
+++ b/core/services/feeds/service_test.go
@@ -1627,7 +1627,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil)
svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -1666,7 +1666,7 @@ answer1 [type=median index=0];
svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(cancelledSpec, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -1784,7 +1784,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil)
},
@@ -1799,7 +1799,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil)
@@ -1815,7 +1815,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil)
svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows)
@@ -1854,7 +1854,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil)
svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows)
@@ -1894,7 +1894,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil)
svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil)
@@ -1953,7 +1953,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist"))
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist"))
},
id: spec.ID,
wantErr: "failed to approve job spec due to bridge check: bridges do not exist",
@@ -1976,7 +1976,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil)
svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, errors.New("failure"))
},
@@ -1991,7 +1991,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil)
svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, errors.New("failure"))
@@ -2007,7 +2007,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil)
svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil)
svc.orm.EXPECT().CancelSpec(int64(100), mock.Anything).Return(errors.New("failure"))
@@ -2023,7 +2023,7 @@ answer1 [type=median index=0];
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil)
svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil)
@@ -2040,7 +2040,7 @@ answer1 [type=median index=0];
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2065,7 +2065,7 @@ answer1 [type=median index=0];
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2096,7 +2096,7 @@ answer1 [type=median index=0];
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2271,7 +2271,7 @@ updateInterval = "20m"
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2309,7 +2309,7 @@ updateInterval = "20m"
svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(cancelledSpec, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2374,7 +2374,7 @@ updateInterval = "20m"
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil)
},
@@ -2389,7 +2389,7 @@ updateInterval = "20m"
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil)
@@ -2434,7 +2434,7 @@ updateInterval = "20m"
Definition: fmt.Sprintf(defn2, externalJobID.String(), &feedID),
}, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, &feedID, mock.Anything).Return(j.ID, nil)
@@ -2473,7 +2473,7 @@ updateInterval = "20m"
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil)
svc.orm.EXPECT().CancelSpec(int64(100), mock.Anything).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
@@ -2561,7 +2561,7 @@ updateInterval = "20m"
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist"))
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist"))
},
id: spec.ID,
wantErr: "failed to approve job spec due to bridge check: bridges do not exist",
@@ -2584,7 +2584,7 @@ updateInterval = "20m"
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2609,7 +2609,7 @@ updateInterval = "20m"
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2640,7 +2640,7 @@ updateInterval = "20m"
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2777,7 +2777,7 @@ chainID = 0
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2815,7 +2815,7 @@ chainID = 0
svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(cancelledSpec, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -2880,7 +2880,7 @@ chainID = 0
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil)
},
@@ -2895,7 +2895,7 @@ chainID = 0
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil)
@@ -2940,7 +2940,7 @@ chainID = 0
Definition: fmt.Sprintf(defn2, externalJobID.String(), feedID),
}, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, &feedID, mock.Anything).Return(j.ID, nil)
@@ -2979,7 +2979,7 @@ chainID = 0
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil)
svc.orm.EXPECT().CancelSpec(int64(100), mock.Anything).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
@@ -3067,7 +3067,7 @@ chainID = 0
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist"))
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist"))
},
id: spec.ID,
wantErr: "failed to approve job spec due to bridge check: bridges do not exist",
@@ -3090,7 +3090,7 @@ chainID = 0
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -3115,7 +3115,7 @@ chainID = 0
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
@@ -3146,7 +3146,7 @@ chainID = 0
svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil)
svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil)
svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil)
- svc.jobORM.On("AssertBridgesExist", mock.IsType(pipeline.Pipeline{})).Return(nil)
+ svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil)
svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows)
svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows)
diff --git a/core/services/fluxmonitorv2/contract_submitter_test.go b/core/services/fluxmonitorv2/contract_submitter_test.go
index 238cf96e033..7dfd92e5acd 100644
--- a/core/services/fluxmonitorv2/contract_submitter_test.go
+++ b/core/services/fluxmonitorv2/contract_submitter_test.go
@@ -15,6 +15,7 @@ import (
)
func TestFluxAggregatorContractSubmitter_Submit(t *testing.T) {
+ t.Parallel()
var (
fluxAggregator = mocks.NewFluxAggregator(t)
orm = fmmocks.NewORM(t)
diff --git a/core/services/fluxmonitorv2/delegate.go b/core/services/fluxmonitorv2/delegate.go
index 1e2eba8d000..72aa04c7201 100644
--- a/core/services/fluxmonitorv2/delegate.go
+++ b/core/services/fluxmonitorv2/delegate.go
@@ -13,7 +13,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
)
@@ -56,10 +55,10 @@ func (d *Delegate) JobType() job.Type {
return job.FluxMonitor
}
-func (d *Delegate) BeforeJobCreated(spec job.Job) {}
-func (d *Delegate) AfterJobCreated(spec job.Job) {}
-func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) BeforeJobCreated(spec job.Job) {}
+func (d *Delegate) AfterJobCreated(spec job.Job) {}
+func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec returns the flux monitor service for the job spec
func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []job.ServiceCtx, err error) {
@@ -71,7 +70,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []
return nil, err
}
cfg := chain.Config()
- strategy := txmgrcommon.NewQueueingTxStrategy(jb.ExternalJobID, cfg.FluxMonitor().DefaultTransactionQueueDepth(), cfg.Database().DefaultQueryTimeout())
+ strategy := txmgrcommon.NewQueueingTxStrategy(jb.ExternalJobID, cfg.FluxMonitor().DefaultTransactionQueueDepth())
var checker txmgr.TransmitCheckerSpec
if chain.Config().FluxMonitor().SimulateTransactions() {
checker.CheckerType = txmgr.TransmitCheckerTypeSimulate
@@ -80,7 +79,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []
fm, err := NewFromJobSpec(
jb,
d.db,
- NewORM(d.db, d.lggr, chain.Config().Database(), chain.TxManager(), strategy, checker),
+ NewORM(d.db, d.lggr, chain.TxManager(), strategy, checker),
d.jobORM,
d.pipelineORM,
NewKeyStore(d.ethKeyStore),
@@ -89,10 +88,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []
d.pipelineRunner,
chain.Config().EVM(),
chain.Config().EVM().GasEstimator(),
- chain.Config().EVM().Transactions(),
- chain.Config().FluxMonitor(),
chain.Config().JobPipeline(),
- chain.Config().Database(),
d.lggr,
)
if err != nil {
diff --git a/core/services/fluxmonitorv2/flux_monitor.go b/core/services/fluxmonitorv2/flux_monitor.go
index 73034faa3ce..5eebb319030 100644
--- a/core/services/fluxmonitorv2/flux_monitor.go
+++ b/core/services/fluxmonitorv2/flux_monitor.go
@@ -16,6 +16,7 @@ import (
"github.com/jmoiron/sqlx"
"github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
@@ -27,7 +28,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/recovery"
"github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2/promfm"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -64,7 +64,7 @@ type FluxMonitor struct {
jobSpec job.Job
spec pipeline.Spec
runner pipeline.Runner
- q pg.Q
+ ds sqlutil.DataSource
orm ORM
jobORM job.ORM
pipelineORM pipeline.ORM
@@ -93,7 +93,7 @@ func NewFluxMonitor(
pipelineRunner pipeline.Runner,
jobSpec job.Job,
spec pipeline.Spec,
- q pg.Q,
+ ds sqlutil.DataSource,
orm ORM,
jobORM job.ORM,
pipelineORM pipeline.ORM,
@@ -111,7 +111,7 @@ func NewFluxMonitor(
chainID *big.Int,
) (*FluxMonitor, error) {
fm := &FluxMonitor{
- q: q,
+ ds: ds,
runner: pipelineRunner,
jobSpec: jobSpec,
spec: spec,
@@ -159,10 +159,7 @@ func NewFromJobSpec(
pipelineRunner pipeline.Runner,
cfg Config,
fcfg EvmFeeConfig,
- ecfg EvmTransactionsConfig,
- fmcfg FluxMonitorConfig,
jcfg JobPipelineConfig,
- dbCfg pg.QConfig,
lggr logger.Logger,
) (*FluxMonitor, error) {
fmSpec := jobSpec.FluxMonitorSpec
@@ -253,7 +250,7 @@ func NewFromJobSpec(
pipelineRunner,
jobSpec,
*jobSpec.PipelineSpec,
- pg.NewQ(db, lggr, dbCfg),
+ db,
orm,
jobORM,
pipelineORM,
@@ -325,7 +322,7 @@ func (fm *FluxMonitor) Close() error {
func (fm *FluxMonitor) JobID() int32 { return fm.spec.JobID }
// HandleLog processes the contract logs
-func (fm *FluxMonitor) HandleLog(broadcast log.Broadcast) {
+func (fm *FluxMonitor) HandleLog(ctx context.Context, broadcast log.Broadcast) {
log := broadcast.DecodedLog()
if log == nil || reflect.ValueOf(log).IsNil() {
fm.logger.Panic("HandleLog: failed to handle log of type nil")
@@ -509,15 +506,16 @@ func (fm *FluxMonitor) SetOracleAddress() error {
}
func (fm *FluxMonitor) processLogs() {
- for !fm.backlog.Empty() {
+ ctx, cancel := fm.chStop.NewCtx()
+ defer cancel()
+
+ for ctx.Err() == nil && !fm.backlog.Empty() {
broadcast := fm.backlog.Take()
- fm.processBroadcast(broadcast)
+ fm.processBroadcast(ctx, broadcast)
}
}
-func (fm *FluxMonitor) processBroadcast(broadcast log.Broadcast) {
- ctx, cancel := fm.chStop.NewCtx()
- defer cancel()
+func (fm *FluxMonitor) processBroadcast(ctx context.Context, broadcast log.Broadcast) {
// If the log is a duplicate of one we've seen before, ignore it (this
// happens because of the LogBroadcaster's backfilling behavior).
consumed, err := fm.logBroadcaster.WasAlreadyConsumed(ctx, broadcast)
@@ -553,7 +551,7 @@ func (fm *FluxMonitor) processBroadcast(broadcast log.Broadcast) {
}
func (fm *FluxMonitor) markLogAsConsumed(ctx context.Context, broadcast log.Broadcast, decodedLog interface{}, started time.Time) {
- if err := fm.logBroadcaster.MarkConsumed(ctx, broadcast); err != nil {
+ if err := fm.logBroadcaster.MarkConsumed(ctx, nil, broadcast); err != nil {
fm.logger.Errorw("Failed to mark log as consumed",
"err", err, "logType", fmt.Sprintf("%T", decodedLog), "log", broadcast.String(), "elapsed", time.Since(started))
}
@@ -608,7 +606,7 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr
var markConsumed = true
defer func() {
if markConsumed {
- if err := fm.logBroadcaster.MarkConsumed(ctx, lb); err != nil {
+ if err := fm.logBroadcaster.MarkConsumed(ctx, nil, lb); err != nil {
fm.logger.Errorw("Failed to mark log consumed", "err", err, "log", lb.String())
}
}
@@ -665,13 +663,13 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr
// We always want to reset the idle timer upon receiving a NewRound log, so we do it before any `return` statements.
fm.pollManager.ResetIdleTimer(log.StartedAt.Uint64())
- mostRecentRoundID, err := fm.orm.MostRecentFluxMonitorRoundID(fm.contractAddress)
+ mostRecentRoundID, err := fm.orm.MostRecentFluxMonitorRoundID(ctx, fm.contractAddress)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
newRoundLogger.Errorf("error fetching Flux Monitor most recent round ID from DB: %v", err)
return
}
- roundStats, jobRunStatus, err := fm.statsAndStatusForRound(logRoundID, 1)
+ roundStats, jobRunStatus, err := fm.statsAndStatusForRound(ctx, logRoundID, 1)
if err != nil {
newRoundLogger.Errorf("error determining round stats / run status for round: %v", err)
return
@@ -680,14 +678,14 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr
if logRoundID < mostRecentRoundID && roundStats.NumNewRoundLogs > 0 {
newRoundLogger.Debugf("Received an older round log (and number of previously received NewRound logs is: %v) - "+
"a possible reorg, hence deleting round ids from %v to %v", roundStats.NumNewRoundLogs, logRoundID, mostRecentRoundID)
- err = fm.orm.DeleteFluxMonitorRoundsBackThrough(fm.contractAddress, logRoundID)
+ err = fm.orm.DeleteFluxMonitorRoundsBackThrough(ctx, fm.contractAddress, logRoundID)
if err != nil {
newRoundLogger.Errorf("error deleting reorged Flux Monitor rounds from DB: %v", err)
return
}
// as all newer stats were deleted, at this point a new round stats entry will be created
- roundStats, err = fm.orm.FindOrCreateFluxMonitorRoundStats(fm.contractAddress, logRoundID, 1)
+ roundStats, err = fm.orm.FindOrCreateFluxMonitorRoundStats(ctx, fm.contractAddress, logRoundID, 1)
if err != nil {
newRoundLogger.Errorf("error determining subsequent round stats for round: %v", err)
return
@@ -771,7 +769,7 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr
return
}
- if !fm.isValidSubmission(newRoundLogger, answer, started) {
+ if !fm.isValidSubmission(ctx, newRoundLogger, answer, started) {
return
}
@@ -779,14 +777,14 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr
newRoundLogger.Error("roundState.PaymentAmount shouldn't be nil")
}
- err = fm.q.Transaction(func(tx pg.Queryer) error {
- if err2 := fm.runner.InsertFinishedRun(run, false, pg.WithQueryer(tx)); err2 != nil {
+ err = fm.Transact(ctx, func(tx sqlutil.DataSource) error {
+ if err2 := fm.runner.InsertFinishedRun(ctx, tx, run, false); err2 != nil {
return err2
}
if err2 := fm.queueTransactionForTxm(ctx, tx, run.ID, answer, roundState.RoundId, &log); err2 != nil {
return err2
}
- return fm.logBroadcaster.MarkConsumed(ctx, lb)
+ return fm.logBroadcaster.MarkConsumed(ctx, tx, lb)
})
// Either the tx failed and we want to reprocess the log, or it succeeded and already marked it consumed
markConsumed = false
@@ -796,6 +794,10 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr
}
}
+func (fm *FluxMonitor) Transact(ctx context.Context, fn func(sqlutil.DataSource) error) error {
+ return sqlutil.TransactDataSource(ctx, fm.ds, nil, fn)
+}
+
var (
// ErrNotEligible defines when the round is not eligible for submission
ErrNotEligible = errors.New("not eligible to submit")
@@ -832,7 +834,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
var markConsumed = true
defer func() {
if markConsumed && broadcast != nil {
- if err := fm.logBroadcaster.MarkConsumed(ctx, broadcast); err != nil {
+ if err := fm.logBroadcaster.MarkConsumed(ctx, nil, broadcast); err != nil {
l.Errorw("Failed to mark log consumed", "err", err, "log", broadcast.String())
}
}
@@ -863,8 +865,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
roundState, err := fm.roundState(0)
if err != nil {
l.Errorw("unable to determine eligibility to submit from FluxAggregator contract", "err", err)
- fm.jobORM.TryRecordError(
- fm.spec.JobID,
+ fm.jobORM.TryRecordError(fm.spec.JobID,
"Unable to call roundState method on provided contract. Check contract address.",
)
@@ -884,8 +885,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
roundStateNew, err2 := fm.roundState(roundState.RoundId)
if err2 != nil {
l.Errorw("unable to determine eligibility to submit from FluxAggregator contract", "err", err2)
- fm.jobORM.TryRecordError(
- fm.spec.JobID,
+ fm.jobORM.TryRecordError(fm.spec.JobID,
"Unable to call roundState method on provided contract. Check contract address.",
)
@@ -909,7 +909,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
}
}()
- roundStats, jobRunStatus, err := fm.statsAndStatusForRound(roundState.RoundId, 0)
+ roundStats, jobRunStatus, err := fm.statsAndStatusForRound(ctx, roundState.RoundId, 0)
if err != nil {
l.Errorw("error determining round stats / run status for round", "err", err)
@@ -977,7 +977,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
return
}
- if !fm.isValidSubmission(l, answer, started) {
+ if !fm.isValidSubmission(ctx, l, answer, started) {
return
}
@@ -1005,8 +1005,8 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
l.Error("roundState.PaymentAmount shouldn't be nil")
}
- err = fm.q.Transaction(func(tx pg.Queryer) error {
- if err2 := fm.runner.InsertFinishedRun(run, true, pg.WithQueryer(tx)); err2 != nil {
+ err = fm.Transact(ctx, func(tx sqlutil.DataSource) error {
+ if err2 := fm.runner.InsertFinishedRun(ctx, tx, run, true); err2 != nil {
return err2
}
if err2 := fm.queueTransactionForTxm(ctx, tx, run.ID, answer, roundState.RoundId, nil); err2 != nil {
@@ -1014,7 +1014,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
}
if broadcast != nil {
// In the case of a flag lowered, the pollEligible call is triggered by a log.
- return fm.logBroadcaster.MarkConsumed(ctx, broadcast)
+ return fm.logBroadcaster.MarkConsumed(ctx, tx, broadcast)
}
return nil
})
@@ -1031,7 +1031,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
// If the answer is outside the allowable range, log an error and don't submit.
// to avoid an onchain reversion.
-func (fm *FluxMonitor) isValidSubmission(l logger.Logger, answer decimal.Decimal, started time.Time) bool {
+func (fm *FluxMonitor) isValidSubmission(ctx context.Context, l logger.Logger, answer decimal.Decimal, started time.Time) bool {
if fm.submissionChecker.IsValid(answer) {
return true
}
@@ -1085,7 +1085,7 @@ func (fm *FluxMonitor) initialRoundState() flux_aggregator_wrapper.OracleRoundSt
return latestRoundState
}
-func (fm *FluxMonitor) queueTransactionForTxm(ctx context.Context, tx pg.Queryer, runID int64, answer decimal.Decimal, roundID uint32, log *flux_aggregator_wrapper.FluxAggregatorNewRound) error {
+func (fm *FluxMonitor) queueTransactionForTxm(ctx context.Context, tx sqlutil.DataSource, runID int64, answer decimal.Decimal, roundID uint32, log *flux_aggregator_wrapper.FluxAggregatorNewRound) error {
// Use pipeline run ID to generate globally unique key that can correlate this run to a Tx
idempotencyKey := fmt.Sprintf("fluxmonitor-%d", runID)
// Submit the Eth Tx
@@ -1105,12 +1105,12 @@ func (fm *FluxMonitor) queueTransactionForTxm(ctx context.Context, tx pg.Queryer
numLogs = 1
}
// Update the flux monitor round stats
- err = fm.orm.UpdateFluxMonitorRoundStats(
+ err = fm.orm.WithDataSource(tx).UpdateFluxMonitorRoundStats(
+ ctx,
fm.contractAddress,
roundID,
runID,
numLogs,
- pg.WithQueryer(tx),
)
if err != nil {
fm.logger.Errorw(
@@ -1124,8 +1124,8 @@ func (fm *FluxMonitor) queueTransactionForTxm(ctx context.Context, tx pg.Queryer
return nil
}
-func (fm *FluxMonitor) statsAndStatusForRound(roundID uint32, newRoundLogs uint) (FluxMonitorRoundStatsV2, pipeline.RunStatus, error) {
- roundStats, err := fm.orm.FindOrCreateFluxMonitorRoundStats(fm.contractAddress, roundID, newRoundLogs)
+func (fm *FluxMonitor) statsAndStatusForRound(ctx context.Context, roundID uint32, newRoundLogs uint) (FluxMonitorRoundStatsV2, pipeline.RunStatus, error) {
+ roundStats, err := fm.orm.FindOrCreateFluxMonitorRoundStats(ctx, fm.contractAddress, roundID, newRoundLogs)
if err != nil {
return FluxMonitorRoundStatsV2{}, pipeline.RunStatusUnknown, err
}
@@ -1133,7 +1133,7 @@ func (fm *FluxMonitor) statsAndStatusForRound(roundID uint32, newRoundLogs uint)
// JobRun will not exist if this is the first time responding to this round
var run pipeline.Run
if roundStats.PipelineRunID.Valid {
- run, err = fm.pipelineORM.FindRun(roundStats.PipelineRunID.Int64)
+ run, err = fm.pipelineORM.FindRun(ctx, roundStats.PipelineRunID.Int64)
if err != nil {
return FluxMonitorRoundStatsV2{}, pipeline.RunStatusUnknown, err
}
diff --git a/core/services/fluxmonitorv2/flux_monitor_test.go b/core/services/fluxmonitorv2/flux_monitor_test.go
index e4db716bbbb..d8713fed997 100644
--- a/core/services/fluxmonitorv2/flux_monitor_test.go
+++ b/core/services/fluxmonitorv2/flux_monitor_test.go
@@ -22,6 +22,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/assets"
"github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/log"
logmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks"
@@ -31,7 +32,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight"
"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/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
corenull "github.com/smartcontractkit/chainlink/v2/core/null"
@@ -40,7 +40,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
jobmocks "github.com/smartcontractkit/chainlink/v2/core/services/job/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
pipelinemocks "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks"
)
@@ -53,8 +52,8 @@ var (
type answerSet struct{ latestAnswer, polledAnswer int64 }
-func newORM(t *testing.T, db *sqlx.DB, cfg pg.QConfig, txm txmgr.TxManager) fluxmonitorv2.ORM {
- return fluxmonitorv2.NewORM(db, logger.TestLogger(t), cfg, txm, txmgrcommon.NewSendEveryStrategy(), txmgr.TransmitCheckerSpec{})
+func newORM(t *testing.T, db *sqlx.DB, txm txmgr.TxManager) fluxmonitorv2.ORM {
+ return fluxmonitorv2.NewORM(db, logger.TestLogger(t), txm, txmgrcommon.NewSendEveryStrategy(), txmgr.TransmitCheckerSpec{})
}
var (
@@ -149,7 +148,7 @@ type setupOptions struct {
// setup sets up a Flux Monitor for testing, allowing the test to provide
// functional options to configure the setup
-func setup(t *testing.T, db *sqlx.DB, optionFns ...func(*setupOptions)) (*fluxmonitorv2.FluxMonitor, *testMocks) {
+func setup(t *testing.T, ds sqlutil.DataSource, optionFns ...func(*setupOptions)) (*fluxmonitorv2.FluxMonitor, *testMocks) {
t.Helper()
testutils.SkipShort(t, "long test")
@@ -190,7 +189,7 @@ func setup(t *testing.T, db *sqlx.DB, optionFns ...func(*setupOptions)) (*fluxmo
tm.pipelineRunner,
job.Job{},
pipelineSpec,
- pg.NewQ(db, lggr, pgtest.NewQConfig(true)),
+ ds,
options.orm,
tm.jobORM,
tm.pipelineORM,
@@ -292,6 +291,7 @@ func setupFullDBWithKey(t *testing.T) (*sqlx.DB, common.Address) {
}
func TestFluxMonitor_PollIfEligible(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
eligible bool
@@ -386,7 +386,7 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) {
}
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(reportableRoundID), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(reportableRoundID), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: reportableRoundID,
@@ -395,12 +395,12 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) {
}, nil)
tm.pipelineORM.
- On("FindRun", run.ID).
+ On("FindRun", mock.Anything, run.ID).
Return(run, nil)
} else {
if tc.connected {
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(reportableRoundID), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(reportableRoundID), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: reportableRoundID,
@@ -469,7 +469,7 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) {
tm.pipelineRunner.On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 1
+ args.Get(2).(*pipeline.Run).ID = 1
}).
Once()
tm.contractSubmitter.
@@ -479,13 +479,14 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) {
tm.orm.
On("UpdateFluxMonitorRoundStats",
+ mock.Anything,
contractAddress,
uint32(reportableRoundID),
int64(1),
mock.Anything,
- mock.Anything,
).
Return(nil)
+ tm.orm.On("WithDataSource", mock.Anything).Return(fluxmonitorv2.ORM(tm.orm))
}
oracles := []common.Address{nodeAddr, testutils.NewAddress()}
@@ -499,6 +500,7 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) {
// If the roundState method is unable to communicate with the contract (possibly due to
// incorrect address) then the pollIfEligible method should create a JobErr record
func TestFluxMonitor_PollIfEligible_Creates_JobErr(t *testing.T) {
+ t.Parallel()
db, nodeAddr := setupStoreWithKey(t)
oracles := []common.Address{nodeAddr, testutils.NewAddress()}
@@ -529,6 +531,7 @@ func TestFluxMonitor_PollIfEligible_Creates_JobErr(t *testing.T) {
}
func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
+ t.Parallel()
db, nodeAddr := setupStoreWithKey(t)
oracles := []common.Address{nodeAddr, testutils.NewAddress()}
@@ -560,6 +563,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
logsAwaiter := cltest.NewAwaiter()
tm.keyStore.On("EnabledKeysForChain", mock.Anything, testutils.FixtureChainID).Return([]ethkey.KeyV2{{Address: nodeAddr}}, nil).Once()
+ tm.orm.On("WithDataSource", mock.Anything).Return(fluxmonitorv2.ORM(tm.orm))
tm.fluxAggregator.On("Address").Return(common.Address{})
tm.fluxAggregator.On("LatestRoundData", nilOpts).Return(freshContractRoundDataResponse()).Maybe()
@@ -573,19 +577,18 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
tm.fluxAggregator.On("OracleRoundState", nilOpts, nodeAddr, uint32(3)).Return(makeRoundStateForRoundID(3), nil).Once()
tm.fluxAggregator.On("OracleRoundState", nilOpts, nodeAddr, uint32(4)).Return(makeRoundStateForRoundID(4), nil).Once()
tm.fluxAggregator.On("GetOracles", nilOpts).Return(oracles, nil)
- // tm.fluxAggregator.On("Address").Return(contractAddress, nil)
tm.logBroadcaster.On("Register", fm, mock.Anything).Return(func() {})
tm.logBroadcaster.On("IsConnected").Return(true).Maybe()
- tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(1), nil)
- tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(3), nil)
- tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(4), nil)
+ tm.orm.On("MostRecentFluxMonitorRoundID", mock.Anything, contractAddress).Return(uint32(1), nil)
+ tm.orm.On("MostRecentFluxMonitorRoundID", mock.Anything, contractAddress).Return(uint32(3), nil)
+ tm.orm.On("MostRecentFluxMonitorRoundID", mock.Anything, contractAddress).Return(uint32(4), nil)
// Round 1
run := &pipeline.Run{ID: 1}
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(1), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(1), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 1,
@@ -605,7 +608,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 1
+ args.Get(2).(*pipeline.Run).ID = 1
}).Once()
tm.contractSubmitter.
On("Submit", mock.Anything, big.NewInt(1), big.NewInt(fetchedValue), buildIdempotencyKey(run.ID)).
@@ -614,18 +617,18 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
tm.orm.
On("UpdateFluxMonitorRoundStats",
+ mock.Anything,
contractAddress,
uint32(1),
mock.AnythingOfType("int64"), //int64(1),
mock.Anything,
- mock.Anything,
).
Return(nil).Once()
// Round 3
run = &pipeline.Run{ID: 2}
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(3), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(3), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 3,
@@ -645,7 +648,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 2
+ args.Get(2).(*pipeline.Run).ID = 2
}).Once()
tm.contractSubmitter.
On("Submit", mock.Anything, big.NewInt(3), big.NewInt(fetchedValue), buildIdempotencyKey(run.ID)).
@@ -653,18 +656,18 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
+ mock.Anything,
contractAddress,
uint32(3),
mock.AnythingOfType("int64"), //int64(2),
mock.Anything,
- mock.Anything,
).
Return(nil).Once()
// Round 4
run = &pipeline.Run{ID: 3}
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(4), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(4), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 3,
@@ -684,7 +687,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 3
+ args.Get(2).(*pipeline.Run).ID = 3
}).Once()
tm.contractSubmitter.
On("Submit", mock.Anything, big.NewInt(4), big.NewInt(fetchedValue), buildIdempotencyKey(run.ID)).
@@ -692,11 +695,11 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
+ mock.Anything,
contractAddress,
uint32(4),
mock.AnythingOfType("int64"), //int64(3),
mock.Anything,
- mock.Anything,
).
Return(nil).
Once().
@@ -711,23 +714,24 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&flux_aggregator_wrapper.FluxAggregatorNewRound{RoundId: big.NewInt(int64(i)), StartedAt: big.NewInt(0)})
logBroadcast.On("String").Maybe().Return("")
tm.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
logBroadcasts = append(logBroadcasts, logBroadcast)
}
-
- fm.HandleLog(logBroadcasts[0]) // Get the checker to start processing a log so we can freeze it
+ ctx := testutils.Context(t)
+ fm.HandleLog(ctx, logBroadcasts[0]) // Get the checker to start processing a log so we can freeze it
readyToFillQueue.AwaitOrFail(t)
- fm.HandleLog(logBroadcasts[1]) // This log is evicted from the priority queue
- fm.HandleLog(logBroadcasts[2])
- fm.HandleLog(logBroadcasts[3])
+ fm.HandleLog(ctx, logBroadcasts[1]) // This log is evicted from the priority queue
+ fm.HandleLog(ctx, logBroadcasts[2])
+ fm.HandleLog(ctx, logBroadcasts[3])
logsAwaiter.ItHappened()
readyToAssert.AwaitOrFail(t)
}
func TestFluxMonitor_TriggerIdleTimeThreshold(t *testing.T) {
+ t.Parallel()
g := gomega.NewWithT(t)
testCases := []struct {
@@ -749,7 +753,7 @@ func TestFluxMonitor_TriggerIdleTimeThreshold(t *testing.T) {
t.Parallel()
var (
- orm = newORM(t, db, pgtest.NewQConfig(true), nil)
+ orm = newORM(t, db, nil)
)
fm, tm := setup(t, db, disablePollTicker(true), disableIdleTimer(tc.idleTimerDisabled), setIdleTimerPeriod(tc.idleDuration), withORM(orm))
@@ -795,8 +799,8 @@ func TestFluxMonitor_TriggerIdleTimeThreshold(t *testing.T) {
tm.logBroadcast.On("DecodedLog").Return(&decodedLog)
tm.logBroadcast.On("String").Maybe().Return("")
tm.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
- fm.HandleLog(tm.logBroadcast)
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
+ fm.HandleLog(testutils.Context(t), tm.logBroadcast)
g.Eventually(chBlock).Should(gomega.BeClosed())
@@ -856,7 +860,7 @@ func TestFluxMonitor_HibernationTickerFiresMultipleTimes(t *testing.T) {
pollOccured <- struct{}{}
})
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(1), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(1), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 1,
@@ -873,7 +877,7 @@ func TestFluxMonitor_HibernationTickerFiresMultipleTimes(t *testing.T) {
// Finds an existing run created by the initial poll
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(1), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(1), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
PipelineRunID: corenull.NewInt64(int64(1), true),
Aggregator: contractAddress,
@@ -881,7 +885,7 @@ func TestFluxMonitor_HibernationTickerFiresMultipleTimes(t *testing.T) {
NumSubmissions: 1,
}, nil).Once()
finishedAt := time.Now()
- tm.pipelineORM.On("FindRun", int64(1)).Return(pipeline.Run{
+ tm.pipelineORM.On("FindRun", mock.Anything, int64(1)).Return(pipeline.Run{
FinishedAt: null.TimeFrom(finishedAt),
}, nil)
@@ -893,7 +897,7 @@ func TestFluxMonitor_HibernationTickerFiresMultipleTimes(t *testing.T) {
pollOccured <- struct{}{}
})
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(2), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(2), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 2,
@@ -904,6 +908,7 @@ func TestFluxMonitor_HibernationTickerFiresMultipleTimes(t *testing.T) {
}
func TestFluxMonitor_HibernationIsEnteredAndRetryTickerStopped(t *testing.T) {
+ t.Parallel()
db, nodeAddr := setupFullDBWithKey(t)
oracles := []common.Address{nodeAddr, testutils.NewAddress()}
@@ -950,7 +955,7 @@ func TestFluxMonitor_HibernationIsEnteredAndRetryTickerStopped(t *testing.T) {
pollOccured <- struct{}{}
})
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, roundOne, mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, roundOne, mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 1,
@@ -970,7 +975,7 @@ func TestFluxMonitor_HibernationIsEnteredAndRetryTickerStopped(t *testing.T) {
// Finds an error run, so that retry ticker will be kicked off
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, roundOne, mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, roundOne, mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
PipelineRunID: corenull.NewInt64(int64(1), true),
Aggregator: contractAddress,
@@ -978,7 +983,7 @@ func TestFluxMonitor_HibernationIsEnteredAndRetryTickerStopped(t *testing.T) {
NumSubmissions: 1,
}, nil).Once()
finishedAt := time.Now()
- tm.pipelineORM.On("FindRun", int64(1)).Return(pipeline.Run{
+ tm.pipelineORM.On("FindRun", mock.Anything, int64(1)).Return(pipeline.Run{
FinishedAt: null.TimeFrom(finishedAt),
FatalErrors: []null.String{null.StringFrom("an error to start retry ticker")},
}, nil)
@@ -997,7 +1002,7 @@ func TestFluxMonitor_HibernationIsEnteredAndRetryTickerStopped(t *testing.T) {
roundState2 := flux_aggregator_wrapper.OracleRoundState{RoundId: 2, EligibleToSubmit: false, LatestSubmission: answerBigInt, StartedAt: 0}
tm.fluxAggregator.On("OracleRoundState", nilOpts, nodeAddr, roundZero).Return(roundState2, nil).Once()
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, roundTwo, mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, roundTwo, mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 2,
@@ -1054,7 +1059,7 @@ func TestFluxMonitor_IdleTimerResetsOnNewRound(t *testing.T) {
roundState1 := flux_aggregator_wrapper.OracleRoundState{RoundId: 1, EligibleToSubmit: false, LatestSubmission: answerBigInt, StartedAt: now()}
tm.fluxAggregator.On("OracleRoundState", nilOpts, nodeAddr, uint32(0)).Return(roundState1, nil).Once()
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(1), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(1), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 1,
@@ -1072,7 +1077,7 @@ func TestFluxMonitor_IdleTimerResetsOnNewRound(t *testing.T) {
})
// Finds an existing run created by the initial poll
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(1), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(1), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
PipelineRunID: corenull.NewInt64(int64(1), true),
Aggregator: contractAddress,
@@ -1080,7 +1085,7 @@ func TestFluxMonitor_IdleTimerResetsOnNewRound(t *testing.T) {
NumSubmissions: 1,
}, nil).Once()
finishedAt := time.Now()
- tm.pipelineORM.On("FindRun", int64(1)).Return(pipeline.Run{
+ tm.pipelineORM.On("FindRun", mock.Anything, int64(1)).Return(pipeline.Run{
FinishedAt: null.TimeFrom(finishedAt),
}, nil)
@@ -1092,7 +1097,7 @@ func TestFluxMonitor_IdleTimerResetsOnNewRound(t *testing.T) {
idleDurationOccured <- struct{}{}
})
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(2), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(2), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 2,
@@ -1107,7 +1112,7 @@ func TestFluxMonitor_IdleTimerResetsOnNewRound(t *testing.T) {
idleDurationOccured <- struct{}{}
})
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(3), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(3), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: 3,
@@ -1118,7 +1123,7 @@ func TestFluxMonitor_IdleTimerResetsOnNewRound(t *testing.T) {
tm.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil).Once()
tm.logBroadcast.On("DecodedLog").Return(&flux_aggregator_wrapper.FluxAggregatorAnswerUpdated{})
tm.logBroadcast.On("String").Maybe().Return("")
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil).Once()
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
fm.ExportedBacklog().Add(fluxmonitorv2.PriorityNewRoundLog, tm.logBroadcast)
fm.ExportedProcessLogs()
@@ -1133,7 +1138,7 @@ func TestFluxMonitor_RoundTimeoutCausesPoll_timesOutAtZero(t *testing.T) {
var (
oracles = []common.Address{nodeAddr, testutils.NewAddress()}
- orm = newORM(t, db, pgtest.NewQConfig(true), nil)
+ orm = newORM(t, db, nil)
)
fm, tm := setup(t, db, disablePollTicker(true), disableIdleTimer(true), withORM(orm))
@@ -1173,6 +1178,7 @@ func TestFluxMonitor_RoundTimeoutCausesPoll_timesOutAtZero(t *testing.T) {
}
func TestFluxMonitor_UsesPreviousRoundStateOnStartup_RoundTimeout(t *testing.T) {
+ t.Parallel()
g := gomega.NewWithT(t)
db, nodeAddr := setupStoreWithKey(t)
@@ -1193,10 +1199,7 @@ func TestFluxMonitor_UsesPreviousRoundStateOnStartup_RoundTimeout(t *testing.T)
t.Run(test.name, func(t *testing.T) {
t.Parallel()
- cfg := configtest.NewTestGeneralConfig(t)
- var (
- orm = newORM(t, db, cfg.Database(), nil)
- )
+ orm := newORM(t, db, nil)
fm, tm := setup(t, db, disablePollTicker(true), disableIdleTimer(true), withORM(orm))
@@ -1237,6 +1240,7 @@ func TestFluxMonitor_UsesPreviousRoundStateOnStartup_RoundTimeout(t *testing.T)
}
func TestFluxMonitor_UsesPreviousRoundStateOnStartup_IdleTimer(t *testing.T) {
+ t.Parallel()
g := gomega.NewWithT(t)
db, nodeAddr := setupStoreWithKey(t)
@@ -1260,11 +1264,7 @@ func TestFluxMonitor_UsesPreviousRoundStateOnStartup_IdleTimer(t *testing.T) {
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
- cfg := configtest.NewTestGeneralConfig(t)
-
- var (
- orm = newORM(t, db, cfg.Database(), nil)
- )
+ orm := newORM(t, db, nil)
fm, tm := setup(t,
db,
@@ -1323,11 +1323,7 @@ func TestFluxMonitor_RoundTimeoutCausesPoll_timesOutNotZero(t *testing.T) {
g := gomega.NewWithT(t)
db, nodeAddr := setupStoreWithKey(t)
oracles := []common.Address{nodeAddr, testutils.NewAddress()}
- cfg := configtest.NewTestGeneralConfig(t)
-
- var (
- orm = newORM(t, db, cfg.Database(), nil)
- )
+ orm := newORM(t, db, nil)
fm, tm := setup(t, db, disablePollTicker(true), disableIdleTimer(true), withORM(orm))
@@ -1381,14 +1377,14 @@ func TestFluxMonitor_RoundTimeoutCausesPoll_timesOutNotZero(t *testing.T) {
servicetest.Run(t, fm)
tm.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
tm.logBroadcast.On("DecodedLog").Return(&flux_aggregator_wrapper.FluxAggregatorNewRound{
RoundId: big.NewInt(0),
StartedAt: big.NewInt(time.Now().UTC().Unix()),
})
tm.logBroadcast.On("String").Maybe().Return("")
// To mark it consumed, we need to be eligible to submit.
- fm.HandleLog(tm.logBroadcast)
+ fm.HandleLog(testutils.Context(t), tm.logBroadcast)
g.Eventually(chRoundState1).Should(gomega.BeClosed())
g.Eventually(chRoundState2).Should(gomega.BeClosed())
@@ -1409,7 +1405,7 @@ func TestFluxMonitor_ConsumeLogBroadcast(t *testing.T) {
tm.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil).Once()
tm.logBroadcast.On("DecodedLog").Return(&flux_aggregator_wrapper.FluxAggregatorAnswerUpdated{})
tm.logBroadcast.On("String").Maybe().Return("")
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil).Once()
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
fm.ExportedBacklog().Add(fluxmonitorv2.PriorityNewRoundLog, tm.logBroadcast)
fm.ExportedProcessLogs()
@@ -1444,6 +1440,7 @@ func TestFluxMonitor_ConsumeLogBroadcast_Error(t *testing.T) {
}
func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
+ t.Parallel()
t.Run("when NewRound log arrives, then poll ticker fires", func(t *testing.T) {
db, nodeAddr := setupStoreWithKey(t)
oracles := []common.Address{nodeAddr, testutils.NewAddress()}
@@ -1468,11 +1465,12 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
tm.keyStore.On("EnabledKeysForChain", mock.Anything, testutils.FixtureChainID).Return([]ethkey.KeyV2{{Address: nodeAddr}}, nil).Once()
tm.logBroadcaster.On("IsConnected").Return(true).Maybe()
+ tm.orm.On("WithDataSource", mock.Anything).Return(fluxmonitorv2.ORM(tm.orm))
// Mocks initiated by the New Round log
- tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(roundID), nil).Once()
+ tm.orm.On("MostRecentFluxMonitorRoundID", mock.Anything, contractAddress).Return(uint32(roundID), nil).Once()
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(roundID), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(roundID), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: roundID,
@@ -1492,17 +1490,17 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 1
+ args.Get(2).(*pipeline.Run).ID = 1
})
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil).Once()
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
tm.contractSubmitter.On("Submit", mock.Anything, big.NewInt(roundID), big.NewInt(answer), buildIdempotencyKey(run.ID)).Return(nil).Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
+ mock.Anything,
contractAddress,
uint32(roundID),
int64(1),
uint(1),
- mock.Anything,
).
Return(nil)
@@ -1545,7 +1543,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
Once()
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(roundID), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(roundID), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
PipelineRunID: corenull.NewInt64(int64(1), true),
Aggregator: contractAddress,
@@ -1554,7 +1552,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
}, nil).Once()
now := time.Now()
- tm.pipelineORM.On("FindRun", int64(1)).Return(pipeline.Run{
+ tm.pipelineORM.On("FindRun", mock.Anything, int64(1)).Return(pipeline.Run{
FinishedAt: null.TimeFrom(now),
}, nil)
@@ -1583,6 +1581,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
run := &pipeline.Run{ID: 1}
tm.keyStore.On("EnabledKeysForChain", mock.Anything, testutils.FixtureChainID).Return([]ethkey.KeyV2{{Address: nodeAddr}}, nil).Once()
tm.logBroadcaster.On("IsConnected").Return(true).Maybe()
+ tm.orm.On("WithDataSource", mock.Anything).Return(fluxmonitorv2.ORM(tm.orm))
// First, force the node to try to poll, which should result in a submission
tm.fluxAggregator.On("LatestRoundData", nilOpts).Return(flux_aggregator_wrapper.LatestRoundData{
@@ -1600,7 +1599,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
}, nil).
Once()
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(roundID), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(roundID), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: roundID,
@@ -1620,16 +1619,16 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 1
+ args.Get(2).(*pipeline.Run).ID = 1
})
tm.contractSubmitter.On("Submit", mock.Anything, big.NewInt(roundID), big.NewInt(answer), buildIdempotencyKey(run.ID)).Return(nil).Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
+ mock.Anything,
contractAddress,
uint32(roundID),
int64(1),
uint(0),
- mock.Anything,
).
Return(nil).
Once()
@@ -1639,18 +1638,18 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
fm.ExportedPollIfEligible(0, 0)
// Now fire off the NewRound log and ensure it does not respond this time
- tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(roundID), nil)
+ tm.orm.On("MostRecentFluxMonitorRoundID", mock.Anything, contractAddress).Return(uint32(roundID), nil)
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(roundID), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(roundID), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
PipelineRunID: corenull.NewInt64(int64(1), true),
Aggregator: contractAddress,
RoundID: roundID,
NumSubmissions: 1,
}, nil).Once()
- tm.pipelineORM.On("FindRun", int64(1)).Return(pipeline.Run{}, nil)
+ tm.pipelineORM.On("FindRun", mock.Anything, int64(1)).Return(pipeline.Run{}, nil)
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
fm.ExportedRespondToNewRoundLog(&flux_aggregator_wrapper.FluxAggregatorNewRound{
RoundId: big.NewInt(roundID),
StartedAt: big.NewInt(0),
@@ -1679,6 +1678,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
run := &pipeline.Run{ID: 1}
tm.keyStore.On("EnabledKeysForChain", mock.Anything, testutils.FixtureChainID).Return([]ethkey.KeyV2{{Address: nodeAddr}}, nil).Once()
tm.logBroadcaster.On("IsConnected").Return(true).Maybe()
+ tm.orm.On("WithDataSource", mock.Anything).Return(fluxmonitorv2.ORM(tm.orm))
// First, force the node to try to poll, which should result in a submission
tm.fluxAggregator.On("LatestRoundData", nilOpts).Return(flux_aggregator_wrapper.LatestRoundData{
@@ -1696,7 +1696,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
}, nil).
Once()
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(roundID), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(roundID), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
Aggregator: contractAddress,
RoundID: roundID,
@@ -1716,16 +1716,16 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 1
+ args.Get(2).(*pipeline.Run).ID = 1
})
tm.contractSubmitter.On("Submit", mock.Anything, big.NewInt(roundID), big.NewInt(answer), buildIdempotencyKey(run.ID)).Return(nil).Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
+ mock.Anything,
contractAddress,
uint32(roundID),
int64(1),
uint(0),
- mock.Anything,
).
Return(nil).
Once()
@@ -1735,27 +1735,27 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
fm.ExportedPollIfEligible(0, 0)
// Now fire off the NewRound log and ensure it does not respond this time
- tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(roundID), nil)
+ tm.orm.On("MostRecentFluxMonitorRoundID", mock.Anything, contractAddress).Return(uint32(roundID), nil)
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(olderRoundID), mock.Anything).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(olderRoundID), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
PipelineRunID: corenull.NewInt64(int64(1), true),
Aggregator: contractAddress,
RoundID: olderRoundID,
NumSubmissions: 1,
}, nil).Once()
- tm.pipelineORM.On("FindRun", int64(1)).Return(pipeline.Run{}, nil)
+ tm.pipelineORM.On("FindRun", mock.Anything, int64(1)).Return(pipeline.Run{}, nil)
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
fm.ExportedRespondToNewRoundLog(&flux_aggregator_wrapper.FluxAggregatorNewRound{
RoundId: big.NewInt(olderRoundID),
StartedAt: big.NewInt(0),
}, log.NewLogBroadcast(types.Log{}, cltest.FixtureChainID, nil))
// Simulate a reorg - fire the same NewRound log again, which should result in a submission this time
- tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(roundID), nil)
+ tm.orm.On("MostRecentFluxMonitorRoundID", mock.Anything, contractAddress).Return(uint32(roundID), nil)
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(olderRoundID), uint(1)).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(olderRoundID), uint(1)).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
PipelineRunID: corenull.NewInt64(int64(1), true),
Aggregator: contractAddress,
@@ -1763,14 +1763,14 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
NumSubmissions: 1,
NumNewRoundLogs: 1,
}, nil).Once()
- tm.pipelineORM.On("FindRun", int64(1)).Return(pipeline.Run{}, nil)
+ tm.pipelineORM.On("FindRun", mock.Anything, int64(1)).Return(pipeline.Run{}, nil)
// all newer round stats should be deleted
- tm.orm.On("DeleteFluxMonitorRoundsBackThrough", contractAddress, uint32(olderRoundID)).Return(nil)
+ tm.orm.On("DeleteFluxMonitorRoundsBackThrough", mock.Anything, contractAddress, uint32(olderRoundID)).Return(nil)
// then we are returning a fresh round stat, with NumSubmissions: 0
tm.orm.
- On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(olderRoundID), uint(1)).
+ On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, uint32(olderRoundID), uint(1)).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
PipelineRunID: corenull.NewInt64(int64(1), true),
Aggregator: contractAddress,
@@ -1795,16 +1795,16 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
tm.orm.
On("UpdateFluxMonitorRoundStats",
+ mock.Anything,
contractAddress,
uint32(olderRoundID),
int64(1),
uint(1),
- mock.Anything,
).
Return(nil).
Once()
- tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
fm.ExportedRespondToNewRoundLog(&flux_aggregator_wrapper.FluxAggregatorNewRound{
RoundId: big.NewInt(olderRoundID),
StartedAt: big.NewInt(0),
@@ -1824,6 +1824,7 @@ func TestFluxMonitor_DrumbeatTicker(t *testing.T) {
fm, tm := setup(t, db, disablePollTicker(true), disableIdleTimer(true), enableDrumbeatTicker("@every 3s", 2*time.Second))
tm.keyStore.On("EnabledKeysForChain", mock.Anything, testutils.FixtureChainID).Return([]ethkey.KeyV2{{Address: nodeAddr}}, nil)
+ tm.orm.On("WithDataSource", mock.Anything).Return(fluxmonitorv2.ORM(tm.orm))
const fetchedAnswer = 100
answerBigInt := big.NewInt(fetchedAnswer)
@@ -1853,7 +1854,7 @@ func TestFluxMonitor_DrumbeatTicker(t *testing.T) {
Return(roundState, nil).
Once()
- tm.orm.On("FindOrCreateFluxMonitorRoundStats", contractAddress, roundID, mock.Anything).
+ tm.orm.On("FindOrCreateFluxMonitorRoundStats", mock.Anything, contractAddress, roundID, mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{Aggregator: contractAddress, RoundID: roundID}, nil).
Once()
@@ -1895,7 +1896,7 @@ func TestFluxMonitor_DrumbeatTicker(t *testing.T) {
tm.pipelineRunner.On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = runID
+ args.Get(2).(*pipeline.Run).ID = runID
}).
Once()
tm.contractSubmitter.
@@ -1904,7 +1905,7 @@ func TestFluxMonitor_DrumbeatTicker(t *testing.T) {
Once()
tm.orm.
- On("UpdateFluxMonitorRoundStats", contractAddress, roundID, runID, mock.Anything, mock.Anything).
+ On("UpdateFluxMonitorRoundStats", mock.Anything, contractAddress, roundID, runID, mock.Anything).
Return(nil).
Once()
}
diff --git a/core/services/fluxmonitorv2/integrations_test.go b/core/services/fluxmonitorv2/integrations_test.go
index b2dc9dd423a..7a967300867 100644
--- a/core/services/fluxmonitorv2/integrations_test.go
+++ b/core/services/fluxmonitorv2/integrations_test.go
@@ -483,7 +483,7 @@ func TestFluxMonitor_Deviation(t *testing.T) {
)
t.Cleanup(mockServer.Close)
u, _ := url.Parse(mockServer.URL)
- require.NoError(t, app.BridgeORM().CreateBridgeType(&bridges.BridgeType{
+ require.NoError(t, app.BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{
Name: "bridge",
URL: models.WebURL(*u),
}))
diff --git a/core/services/fluxmonitorv2/mocks/orm.go b/core/services/fluxmonitorv2/mocks/orm.go
index 287c7ebb5fa..e5173db8264 100644
--- a/core/services/fluxmonitorv2/mocks/orm.go
+++ b/core/services/fluxmonitorv2/mocks/orm.go
@@ -11,7 +11,7 @@ import (
mock "github.com/stretchr/testify/mock"
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
)
// ORM is an autogenerated mock type for the ORM type
@@ -19,9 +19,9 @@ type ORM struct {
mock.Mock
}
-// CountFluxMonitorRoundStats provides a mock function with given fields:
-func (_m *ORM) CountFluxMonitorRoundStats() (int, error) {
- ret := _m.Called()
+// CountFluxMonitorRoundStats provides a mock function with given fields: ctx
+func (_m *ORM) CountFluxMonitorRoundStats(ctx context.Context) (int, error) {
+ ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for CountFluxMonitorRoundStats")
@@ -29,17 +29,17 @@ func (_m *ORM) CountFluxMonitorRoundStats() (int, error) {
var r0 int
var r1 error
- if rf, ok := ret.Get(0).(func() (int, error)); ok {
- return rf()
+ if rf, ok := ret.Get(0).(func(context.Context) (int, error)); ok {
+ return rf(ctx)
}
- if rf, ok := ret.Get(0).(func() int); ok {
- r0 = rf()
+ if rf, ok := ret.Get(0).(func(context.Context) int); ok {
+ r0 = rf(ctx)
} else {
r0 = ret.Get(0).(int)
}
- if rf, ok := ret.Get(1).(func() error); ok {
- r1 = rf()
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
@@ -65,17 +65,17 @@ func (_m *ORM) CreateEthTransaction(ctx context.Context, fromAddress common.Addr
return r0
}
-// DeleteFluxMonitorRoundsBackThrough provides a mock function with given fields: aggregator, roundID
-func (_m *ORM) DeleteFluxMonitorRoundsBackThrough(aggregator common.Address, roundID uint32) error {
- ret := _m.Called(aggregator, roundID)
+// DeleteFluxMonitorRoundsBackThrough provides a mock function with given fields: ctx, aggregator, roundID
+func (_m *ORM) DeleteFluxMonitorRoundsBackThrough(ctx context.Context, aggregator common.Address, roundID uint32) error {
+ ret := _m.Called(ctx, aggregator, roundID)
if len(ret) == 0 {
panic("no return value specified for DeleteFluxMonitorRoundsBackThrough")
}
var r0 error
- if rf, ok := ret.Get(0).(func(common.Address, uint32) error); ok {
- r0 = rf(aggregator, roundID)
+ if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint32) error); ok {
+ r0 = rf(ctx, aggregator, roundID)
} else {
r0 = ret.Error(0)
}
@@ -83,9 +83,9 @@ func (_m *ORM) DeleteFluxMonitorRoundsBackThrough(aggregator common.Address, rou
return r0
}
-// FindOrCreateFluxMonitorRoundStats provides a mock function with given fields: aggregator, roundID, newRoundLogs
-func (_m *ORM) FindOrCreateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, newRoundLogs uint) (fluxmonitorv2.FluxMonitorRoundStatsV2, error) {
- ret := _m.Called(aggregator, roundID, newRoundLogs)
+// FindOrCreateFluxMonitorRoundStats provides a mock function with given fields: ctx, aggregator, roundID, newRoundLogs
+func (_m *ORM) FindOrCreateFluxMonitorRoundStats(ctx context.Context, aggregator common.Address, roundID uint32, newRoundLogs uint) (fluxmonitorv2.FluxMonitorRoundStatsV2, error) {
+ ret := _m.Called(ctx, aggregator, roundID, newRoundLogs)
if len(ret) == 0 {
panic("no return value specified for FindOrCreateFluxMonitorRoundStats")
@@ -93,17 +93,17 @@ func (_m *ORM) FindOrCreateFluxMonitorRoundStats(aggregator common.Address, roun
var r0 fluxmonitorv2.FluxMonitorRoundStatsV2
var r1 error
- if rf, ok := ret.Get(0).(func(common.Address, uint32, uint) (fluxmonitorv2.FluxMonitorRoundStatsV2, error)); ok {
- return rf(aggregator, roundID, newRoundLogs)
+ if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint32, uint) (fluxmonitorv2.FluxMonitorRoundStatsV2, error)); ok {
+ return rf(ctx, aggregator, roundID, newRoundLogs)
}
- if rf, ok := ret.Get(0).(func(common.Address, uint32, uint) fluxmonitorv2.FluxMonitorRoundStatsV2); ok {
- r0 = rf(aggregator, roundID, newRoundLogs)
+ if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint32, uint) fluxmonitorv2.FluxMonitorRoundStatsV2); ok {
+ r0 = rf(ctx, aggregator, roundID, newRoundLogs)
} else {
r0 = ret.Get(0).(fluxmonitorv2.FluxMonitorRoundStatsV2)
}
- if rf, ok := ret.Get(1).(func(common.Address, uint32, uint) error); ok {
- r1 = rf(aggregator, roundID, newRoundLogs)
+ if rf, ok := ret.Get(1).(func(context.Context, common.Address, uint32, uint) error); ok {
+ r1 = rf(ctx, aggregator, roundID, newRoundLogs)
} else {
r1 = ret.Error(1)
}
@@ -111,9 +111,9 @@ func (_m *ORM) FindOrCreateFluxMonitorRoundStats(aggregator common.Address, roun
return r0, r1
}
-// MostRecentFluxMonitorRoundID provides a mock function with given fields: aggregator
-func (_m *ORM) MostRecentFluxMonitorRoundID(aggregator common.Address) (uint32, error) {
- ret := _m.Called(aggregator)
+// MostRecentFluxMonitorRoundID provides a mock function with given fields: ctx, aggregator
+func (_m *ORM) MostRecentFluxMonitorRoundID(ctx context.Context, aggregator common.Address) (uint32, error) {
+ ret := _m.Called(ctx, aggregator)
if len(ret) == 0 {
panic("no return value specified for MostRecentFluxMonitorRoundID")
@@ -121,17 +121,17 @@ func (_m *ORM) MostRecentFluxMonitorRoundID(aggregator common.Address) (uint32,
var r0 uint32
var r1 error
- if rf, ok := ret.Get(0).(func(common.Address) (uint32, error)); ok {
- return rf(aggregator)
+ if rf, ok := ret.Get(0).(func(context.Context, common.Address) (uint32, error)); ok {
+ return rf(ctx, aggregator)
}
- if rf, ok := ret.Get(0).(func(common.Address) uint32); ok {
- r0 = rf(aggregator)
+ if rf, ok := ret.Get(0).(func(context.Context, common.Address) uint32); ok {
+ r0 = rf(ctx, aggregator)
} else {
r0 = ret.Get(0).(uint32)
}
- if rf, ok := ret.Get(1).(func(common.Address) error); ok {
- r1 = rf(aggregator)
+ if rf, ok := ret.Get(1).(func(context.Context, common.Address) error); ok {
+ r1 = rf(ctx, aggregator)
} else {
r1 = ret.Error(1)
}
@@ -139,24 +139,17 @@ func (_m *ORM) MostRecentFluxMonitorRoundID(aggregator common.Address) (uint32,
return r0, r1
}
-// UpdateFluxMonitorRoundStats provides a mock function with given fields: aggregator, roundID, runID, newRoundLogsAddition, qopts
-func (_m *ORM) UpdateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, aggregator, roundID, runID, newRoundLogsAddition)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// UpdateFluxMonitorRoundStats provides a mock function with given fields: ctx, aggregator, roundID, runID, newRoundLogsAddition
+func (_m *ORM) UpdateFluxMonitorRoundStats(ctx context.Context, aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint) error {
+ ret := _m.Called(ctx, aggregator, roundID, runID, newRoundLogsAddition)
if len(ret) == 0 {
panic("no return value specified for UpdateFluxMonitorRoundStats")
}
var r0 error
- if rf, ok := ret.Get(0).(func(common.Address, uint32, int64, uint, ...pg.QOpt) error); ok {
- r0 = rf(aggregator, roundID, runID, newRoundLogsAddition, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint32, int64, uint) error); ok {
+ r0 = rf(ctx, aggregator, roundID, runID, newRoundLogsAddition)
} else {
r0 = ret.Error(0)
}
@@ -164,6 +157,26 @@ func (_m *ORM) UpdateFluxMonitorRoundStats(aggregator common.Address, roundID ui
return r0
}
+// WithDataSource provides a mock function with given fields: _a0
+func (_m *ORM) WithDataSource(_a0 sqlutil.DataSource) fluxmonitorv2.ORM {
+ ret := _m.Called(_a0)
+
+ if len(ret) == 0 {
+ panic("no return value specified for WithDataSource")
+ }
+
+ var r0 fluxmonitorv2.ORM
+ if rf, ok := ret.Get(0).(func(sqlutil.DataSource) fluxmonitorv2.ORM); ok {
+ r0 = rf(_a0)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(fluxmonitorv2.ORM)
+ }
+ }
+
+ return r0
+}
+
// NewORM creates a new instance of ORM. 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 NewORM(t interface {
diff --git a/core/services/fluxmonitorv2/orm.go b/core/services/fluxmonitorv2/orm.go
index 91973387e32..e090b84ed04 100644
--- a/core/services/fluxmonitorv2/orm.go
+++ b/core/services/fluxmonitorv2/orm.go
@@ -7,12 +7,10 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
- "github.com/jmoiron/sqlx"
-
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/common/txmgr/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
type transmitter interface {
@@ -23,48 +21,49 @@ type transmitter interface {
// ORM defines an interface for database commands related to Flux Monitor v2
type ORM interface {
- MostRecentFluxMonitorRoundID(aggregator common.Address) (uint32, error)
- DeleteFluxMonitorRoundsBackThrough(aggregator common.Address, roundID uint32) error
- FindOrCreateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, newRoundLogs uint) (FluxMonitorRoundStatsV2, error)
- UpdateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint, qopts ...pg.QOpt) error
+ MostRecentFluxMonitorRoundID(ctx context.Context, aggregator common.Address) (uint32, error)
+ DeleteFluxMonitorRoundsBackThrough(ctx context.Context, aggregator common.Address, roundID uint32) error
+ FindOrCreateFluxMonitorRoundStats(ctx context.Context, aggregator common.Address, roundID uint32, newRoundLogs uint) (FluxMonitorRoundStatsV2, error)
+ UpdateFluxMonitorRoundStats(ctx context.Context, aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint) error
CreateEthTransaction(ctx context.Context, fromAddress, toAddress common.Address, payload []byte, gasLimit uint64, idempotencyKey *string) error
- CountFluxMonitorRoundStats() (count int, err error)
+ CountFluxMonitorRoundStats(ctx context.Context) (count int, err error)
+
+ WithDataSource(sqlutil.DataSource) ORM
}
type orm struct {
- q pg.Q
+ ds sqlutil.DataSource
txm transmitter
strategy types.TxStrategy
checker txmgr.TransmitCheckerSpec
logger logger.Logger
}
+func (o *orm) WithDataSource(ds sqlutil.DataSource) ORM { return o.withDataSource(ds) }
+
+func (o *orm) withDataSource(ds sqlutil.DataSource) *orm {
+ return &orm{ds, o.txm, o.strategy, o.checker, o.logger}
+}
+
// NewORM initializes a new ORM
-func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, txm transmitter, strategy types.TxStrategy, checker txmgr.TransmitCheckerSpec) ORM {
+func NewORM(ds sqlutil.DataSource, lggr logger.Logger, txm transmitter, strategy types.TxStrategy, checker txmgr.TransmitCheckerSpec) ORM {
namedLogger := lggr.Named("FluxMonitorORM")
- q := pg.NewQ(db, namedLogger, cfg)
- return &orm{
- q,
- txm,
- strategy,
- checker,
- namedLogger,
- }
+ return &orm{ds, txm, strategy, checker, namedLogger}
}
// MostRecentFluxMonitorRoundID finds roundID of the most recent round that the
// provided oracle address submitted to
-func (o *orm) MostRecentFluxMonitorRoundID(aggregator common.Address) (uint32, error) {
+func (o *orm) MostRecentFluxMonitorRoundID(ctx context.Context, aggregator common.Address) (uint32, error) {
var stats FluxMonitorRoundStatsV2
- err := o.q.Get(&stats, `SELECT * FROM flux_monitor_round_stats_v2 WHERE aggregator = $1 ORDER BY round_id DESC LIMIT 1`, aggregator)
+ err := o.ds.GetContext(ctx, &stats, `SELECT * FROM flux_monitor_round_stats_v2 WHERE aggregator = $1 ORDER BY round_id DESC LIMIT 1`, aggregator)
return stats.RoundID, errors.Wrap(err, "MostRecentFluxMonitorRoundID failed")
}
// DeleteFluxMonitorRoundsBackThrough deletes all the RoundStat records for a
// given oracle address starting from the most recent round back through the
// given round
-func (o *orm) DeleteFluxMonitorRoundsBackThrough(aggregator common.Address, roundID uint32) error {
- _, err := o.q.Exec(`
+func (o *orm) DeleteFluxMonitorRoundsBackThrough(ctx context.Context, aggregator common.Address, roundID uint32) error {
+ _, err := o.ds.ExecContext(ctx, `
DELETE FROM flux_monitor_round_stats_v2
WHERE aggregator = $1
AND round_id >= $2
@@ -74,14 +73,14 @@ func (o *orm) DeleteFluxMonitorRoundsBackThrough(aggregator common.Address, roun
// FindOrCreateFluxMonitorRoundStats find the round stats record for a given
// oracle on a given round, or creates it if no record exists
-func (o *orm) FindOrCreateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, newRoundLogs uint) (stats FluxMonitorRoundStatsV2, err error) {
- err = o.q.Transaction(func(tx pg.Queryer) error {
- err = tx.Get(&stats,
+func (o *orm) FindOrCreateFluxMonitorRoundStats(ctx context.Context, aggregator common.Address, roundID uint32, newRoundLogs uint) (stats FluxMonitorRoundStatsV2, err error) {
+ err = sqlutil.Transact(ctx, o.withDataSource, o.ds, nil, func(tx *orm) error {
+ err = tx.ds.GetContext(ctx, &stats,
`INSERT INTO flux_monitor_round_stats_v2 (aggregator, round_id, num_new_round_logs, num_submissions) VALUES ($1, $2, $3, 0)
ON CONFLICT (aggregator, round_id) DO NOTHING`,
aggregator, roundID, newRoundLogs)
if errors.Is(err, sql.ErrNoRows) {
- err = tx.Get(&stats, `SELECT * FROM flux_monitor_round_stats_v2 WHERE aggregator=$1 AND round_id=$2`, aggregator, roundID)
+ err = tx.ds.GetContext(ctx, &stats, `SELECT * FROM flux_monitor_round_stats_v2 WHERE aggregator=$1 AND round_id=$2`, aggregator, roundID)
}
return err
})
@@ -91,9 +90,8 @@ func (o *orm) FindOrCreateFluxMonitorRoundStats(aggregator common.Address, round
// UpdateFluxMonitorRoundStats trys to create a RoundStat record for the given oracle
// at the given round. If one already exists, it increments the num_submissions column.
-func (o *orm) UpdateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint, qopts ...pg.QOpt) error {
- q := o.q.WithOpts(qopts...)
- err := q.ExecQ(`
+func (o *orm) UpdateFluxMonitorRoundStats(ctx context.Context, aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint) error {
+ _, err := o.ds.ExecContext(ctx, `
INSERT INTO flux_monitor_round_stats_v2 (
aggregator, round_id, pipeline_run_id, num_new_round_logs, num_submissions
) VALUES (
@@ -108,8 +106,8 @@ func (o *orm) UpdateFluxMonitorRoundStats(aggregator common.Address, roundID uin
}
// CountFluxMonitorRoundStats counts the total number of records
-func (o *orm) CountFluxMonitorRoundStats() (count int, err error) {
- err = o.q.Get(&count, `SELECT count(*) FROM flux_monitor_round_stats_v2`)
+func (o *orm) CountFluxMonitorRoundStats(ctx context.Context) (count int, err error) {
+ err = o.ds.GetContext(ctx, &count, `SELECT count(*) FROM flux_monitor_round_stats_v2`)
return count, errors.Wrap(err, "CountFluxMonitorRoundStats failed")
}
diff --git a/core/services/fluxmonitorv2/orm_test.go b/core/services/fluxmonitorv2/orm_test.go
index 9f85a99b6ea..f6904b9fe97 100644
--- a/core/services/fluxmonitorv2/orm_test.go
+++ b/core/services/fluxmonitorv2/orm_test.go
@@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable"
+ "github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
commontxmmocks "github.com/smartcontractkit/chainlink/v2/common/txmgr/types/mocks"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
@@ -28,61 +29,62 @@ import (
func TestORM_MostRecentFluxMonitorRoundID(t *testing.T) {
t.Parallel()
+ ctx := tests.Context(t)
db := pgtest.NewSqlxDB(t)
- cfg := pgtest.NewQConfig(true)
- orm := newORM(t, db, cfg, nil)
+ orm := newORM(t, db, nil)
address := testutils.NewAddress()
// Setup the rounds
for round := uint32(0); round < 10; round++ {
- _, err := orm.FindOrCreateFluxMonitorRoundStats(address, round, 1)
+ _, err := orm.FindOrCreateFluxMonitorRoundStats(ctx, address, round, 1)
require.NoError(t, err)
}
- count, err := orm.CountFluxMonitorRoundStats()
+ count, err := orm.CountFluxMonitorRoundStats(ctx)
require.NoError(t, err)
require.Equal(t, 10, count)
// Ensure round stats are not created again for the same address/roundID
- stats, err := orm.FindOrCreateFluxMonitorRoundStats(address, uint32(0), 1)
+ stats, err := orm.FindOrCreateFluxMonitorRoundStats(ctx, address, uint32(0), 1)
require.NoError(t, err)
require.Equal(t, uint32(0), stats.RoundID)
require.Equal(t, address, stats.Aggregator)
require.Equal(t, uint64(1), stats.NumNewRoundLogs)
- count, err = orm.CountFluxMonitorRoundStats()
+ count, err = orm.CountFluxMonitorRoundStats(ctx)
require.NoError(t, err)
require.Equal(t, 10, count)
- roundID, err := orm.MostRecentFluxMonitorRoundID(testutils.NewAddress())
+ roundID, err := orm.MostRecentFluxMonitorRoundID(ctx, testutils.NewAddress())
require.Error(t, err)
require.Equal(t, uint32(0), roundID)
- roundID, err = orm.MostRecentFluxMonitorRoundID(address)
+ roundID, err = orm.MostRecentFluxMonitorRoundID(ctx, address)
require.NoError(t, err)
require.Equal(t, uint32(9), roundID)
// Deleting rounds against a new address should incur no changes
- err = orm.DeleteFluxMonitorRoundsBackThrough(testutils.NewAddress(), 5)
+ err = orm.DeleteFluxMonitorRoundsBackThrough(ctx, testutils.NewAddress(), 5)
require.NoError(t, err)
- count, err = orm.CountFluxMonitorRoundStats()
+ count, err = orm.CountFluxMonitorRoundStats(ctx)
require.NoError(t, err)
require.Equal(t, 10, count)
// Deleting rounds against the address
- err = orm.DeleteFluxMonitorRoundsBackThrough(address, 5)
+ err = orm.DeleteFluxMonitorRoundsBackThrough(ctx, address, 5)
require.NoError(t, err)
- count, err = orm.CountFluxMonitorRoundStats()
+ count, err = orm.CountFluxMonitorRoundStats(ctx)
require.NoError(t, err)
require.Equal(t, 5, count)
}
func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) {
t.Parallel()
+ ctx := tests.Context(t)
cfg := configtest.NewGeneralConfig(t, nil)
db := pgtest.NewSqlxDB(t)
@@ -92,13 +94,13 @@ func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) {
// Instantiate a real pipeline ORM because we need to create a pipeline run
// for the foreign key constraint of the stats record
- pipelineORM := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- bridgeORM := bridges.NewORM(db, lggr, cfg.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns())
+ bridgeORM := bridges.NewORM(db)
// Instantiate a real job ORM because we need to create a job to satisfy
// a check in pipeline.CreateRun
jobORM := job.NewORM(db, pipelineORM, bridgeORM, keyStore, lggr, cfg.Database())
- orm := newORM(t, db, cfg.Database(), nil)
+ orm := newORM(t, db, nil)
address := testutils.NewAddress()
var roundID uint32 = 1
@@ -129,13 +131,13 @@ func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) {
},
},
}
- err := pipelineORM.InsertFinishedRun(run, true)
+ err := pipelineORM.InsertFinishedRun(ctx, run, true)
require.NoError(t, err)
- err = orm.UpdateFluxMonitorRoundStats(address, roundID, run.ID, 0)
+ err = orm.UpdateFluxMonitorRoundStats(ctx, address, roundID, run.ID, 0)
require.NoError(t, err)
- stats, err := orm.FindOrCreateFluxMonitorRoundStats(address, roundID, 0)
+ stats, err := orm.FindOrCreateFluxMonitorRoundStats(ctx, address, roundID, 0)
require.NoError(t, err)
require.Equal(t, expectedCount, stats.NumSubmissions)
require.True(t, stats.PipelineRunID.Valid)
@@ -177,7 +179,7 @@ func TestORM_CreateEthTransaction(t *testing.T) {
var (
txm = txmmocks.NewMockEvmTxManager(t)
- orm = fluxmonitorv2.NewORM(db, logger.TestLogger(t), cfg, txm, strategy, txmgr.TransmitCheckerSpec{})
+ orm = fluxmonitorv2.NewORM(db, logger.TestLogger(t), txm, strategy, txmgr.TransmitCheckerSpec{})
_, from = cltest.MustInsertRandomKey(t, ethKeyStore)
to = testutils.NewAddress()
diff --git a/core/services/fluxmonitorv2/payment_checker_test.go b/core/services/fluxmonitorv2/payment_checker_test.go
index baec5642339..88643a69fb2 100644
--- a/core/services/fluxmonitorv2/payment_checker_test.go
+++ b/core/services/fluxmonitorv2/payment_checker_test.go
@@ -11,6 +11,7 @@ import (
)
func TestPaymentChecker_SufficientFunds(t *testing.T) {
+ t.Parallel()
var (
checker = fluxmonitorv2.NewPaymentChecker(nil, nil)
payment = 100
@@ -44,6 +45,7 @@ func TestPaymentChecker_SufficientFunds(t *testing.T) {
}
func TestPaymentChecker_SufficientPayment(t *testing.T) {
+ t.Parallel()
var (
payment int64 = 10
eq = payment
diff --git a/core/services/fluxmonitorv2/poll_manager_test.go b/core/services/fluxmonitorv2/poll_manager_test.go
index 9245c309c27..be6aa9a819b 100644
--- a/core/services/fluxmonitorv2/poll_manager_test.go
+++ b/core/services/fluxmonitorv2/poll_manager_test.go
@@ -84,6 +84,7 @@ func watchTicks(t *testing.T, pm *fluxmonitorv2.PollManager, waitDuration time.D
}
func TestPollManager_PollTicker(t *testing.T) {
+ t.Parallel()
pm, err := fluxmonitorv2.NewPollManager(fluxmonitorv2.PollManagerConfig{
PollTickerInterval: pollTickerDefaultDuration,
PollTickerDisabled: false,
@@ -104,6 +105,7 @@ func TestPollManager_PollTicker(t *testing.T) {
}
func TestPollManager_IdleTimer(t *testing.T) {
+ t.Parallel()
pm, err := fluxmonitorv2.NewPollManager(fluxmonitorv2.PollManagerConfig{
PollTickerInterval: 100 * time.Millisecond,
PollTickerDisabled: true,
@@ -126,6 +128,7 @@ func TestPollManager_IdleTimer(t *testing.T) {
}
func TestPollManager_RoundTimer(t *testing.T) {
+ t.Parallel()
pm, err := fluxmonitorv2.NewPollManager(fluxmonitorv2.PollManagerConfig{
PollTickerInterval: pollTickerDefaultDuration,
PollTickerDisabled: true,
@@ -149,6 +152,7 @@ func TestPollManager_RoundTimer(t *testing.T) {
}
func TestPollManager_RetryTimer(t *testing.T) {
+ t.Parallel()
pm, err := fluxmonitorv2.NewPollManager(fluxmonitorv2.PollManagerConfig{
PollTickerInterval: pollTickerDefaultDuration,
PollTickerDisabled: true,
@@ -185,6 +189,7 @@ func TestPollManager_RetryTimer(t *testing.T) {
}
func TestPollManager_InitialPoll(t *testing.T) {
+ t.Parallel()
pm := newPollManager(t)
pm.Start(false, flux_aggregator_wrapper.OracleRoundState{})
@@ -193,6 +198,7 @@ func TestPollManager_InitialPoll(t *testing.T) {
}
func TestPollManager_HibernationTimer(t *testing.T) {
+ t.Parallel()
pm, err := fluxmonitorv2.NewPollManager(fluxmonitorv2.PollManagerConfig{
PollTickerInterval: pollTickerDefaultDuration,
PollTickerDisabled: true,
@@ -214,6 +220,7 @@ func TestPollManager_HibernationTimer(t *testing.T) {
}
func TestPollManager_HibernationOnStartThenAwaken(t *testing.T) {
+ t.Parallel()
pm, err := fluxmonitorv2.NewPollManager(fluxmonitorv2.PollManagerConfig{
PollTickerInterval: pollTickerDefaultDuration,
PollTickerDisabled: false,
@@ -248,6 +255,7 @@ func TestPollManager_HibernationOnStartThenAwaken(t *testing.T) {
}
func TestPollManager_AwakeOnStartThenHibernate(t *testing.T) {
+ t.Parallel()
pm := newPollManager(t)
pm.Start(false, flux_aggregator_wrapper.OracleRoundState{
@@ -272,6 +280,7 @@ func TestPollManager_AwakeOnStartThenHibernate(t *testing.T) {
}
func TestPollManager_ShouldPerformInitialPoll(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
pollTickerDisabled bool
@@ -339,6 +348,7 @@ func TestPollManager_ShouldPerformInitialPoll(t *testing.T) {
}
func TestPollManager_Stop(t *testing.T) {
+ t.Parallel()
pm := newPollManager(t)
pm.Start(false, flux_aggregator_wrapper.OracleRoundState{
@@ -362,6 +372,7 @@ func TestPollManager_Stop(t *testing.T) {
}
func TestPollManager_ResetIdleTimer(t *testing.T) {
+ t.Parallel()
pm := newPollManager(t)
// Start again in awake mode
@@ -382,6 +393,7 @@ func TestPollManager_ResetIdleTimer(t *testing.T) {
}
func TestPollManager_ResetIdleTimerWhenHibernating(t *testing.T) {
+ t.Parallel()
pm := newPollManager(t)
// Start in hibernation
@@ -402,6 +414,7 @@ func TestPollManager_ResetIdleTimerWhenHibernating(t *testing.T) {
}
func TestPollManager_Reset(t *testing.T) {
+ t.Parallel()
pm := newPollManager(t)
// Start again in awake mode
@@ -429,6 +442,7 @@ func TestPollManager_Reset(t *testing.T) {
}
func TestPollManager_ResetWhenHibernating(t *testing.T) {
+ t.Parallel()
pm := newPollManager(t)
// Start in hibernation
diff --git a/core/services/fluxmonitorv2/submission_checker_test.go b/core/services/fluxmonitorv2/submission_checker_test.go
index f8c63fef4bd..ae543c772a5 100644
--- a/core/services/fluxmonitorv2/submission_checker_test.go
+++ b/core/services/fluxmonitorv2/submission_checker_test.go
@@ -11,6 +11,7 @@ import (
)
func TestSubmissionChecker_IsValid(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
answer decimal.Decimal
diff --git a/core/services/fluxmonitorv2/validate_test.go b/core/services/fluxmonitorv2/validate_test.go
index 40efd1d724d..81d9215bea8 100644
--- a/core/services/fluxmonitorv2/validate_test.go
+++ b/core/services/fluxmonitorv2/validate_test.go
@@ -21,6 +21,7 @@ func (testcfg) DefaultHTTPTimeout() commonconfig.Duration {
}
func TestValidate(t *testing.T) {
+ t.Parallel()
var tt = []struct {
name string
toml string
diff --git a/core/services/functions/external_adapter_client.go b/core/services/functions/external_adapter_client.go
index 9dc77ca78e9..09ce8defdca 100644
--- a/core/services/functions/external_adapter_client.go
+++ b/core/services/functions/external_adapter_client.go
@@ -53,7 +53,7 @@ var _ ExternalAdapterClient = (*externalAdapterClient)(nil)
//go:generate mockery --quiet --name BridgeAccessor --output ./mocks/ --case=underscore
type BridgeAccessor interface {
- NewExternalAdapterClient() (ExternalAdapterClient, error)
+ NewExternalAdapterClient(context.Context) (ExternalAdapterClient, error)
}
type bridgeAccessor struct {
@@ -267,8 +267,8 @@ func NewBridgeAccessor(bridgeORM bridges.ORM, bridgeName string, maxResponseByte
}
}
-func (b *bridgeAccessor) NewExternalAdapterClient() (ExternalAdapterClient, error) {
- bridge, err := b.bridgeORM.FindBridge(bridges.BridgeName(b.bridgeName))
+func (b *bridgeAccessor) NewExternalAdapterClient(ctx context.Context) (ExternalAdapterClient, error) {
+ bridge, err := b.bridgeORM.FindBridge(ctx, bridges.BridgeName(b.bridgeName))
if err != nil {
return nil, err
}
diff --git a/core/services/functions/listener.go b/core/services/functions/listener.go
index 12516005c3d..d2033ff74de 100644
--- a/core/services/functions/listener.go
+++ b/core/services/functions/listener.go
@@ -23,7 +23,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/threshold"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
evmrelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/services/s4"
"github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem"
@@ -270,7 +269,7 @@ func (l *functionsListener) setError(ctx context.Context, requestId RequestID, e
promRequestComputationError.WithLabelValues(l.contractAddressHex).Inc()
}
readyForProcessing := errType != INTERNAL_ERROR
- if err := l.pluginORM.SetError(requestId, errType, errBytes, time.Now(), readyForProcessing, pg.WithParentCtx(ctx)); err != nil {
+ if err := l.pluginORM.SetError(ctx, requestId, errType, errBytes, time.Now(), readyForProcessing); err != nil {
l.logger.Errorw("call to SetError failed", "requestID", formatRequestId(requestId), "err", err)
}
}
@@ -321,7 +320,7 @@ func (l *functionsListener) HandleOffchainRequest(ctx context.Context, request *
CoordinatorContractAddress: &senderAddr,
OnchainMetadata: []byte(OffchainRequestMarker),
}
- if err := l.pluginORM.CreateRequest(newReq, pg.WithParentCtx(ctx)); err != nil {
+ if err := l.pluginORM.CreateRequest(ctx, newReq); err != nil {
if errors.Is(err, ErrDuplicateRequestID) {
l.logger.Warnw("HandleOffchainRequest: received duplicate request ID", "requestID", formatRequestId(requestId), "err", err)
} else {
@@ -348,7 +347,7 @@ func (l *functionsListener) handleOracleRequestV1(request *evmrelayTypes.OracleR
CoordinatorContractAddress: &request.CoordinatorContract,
OnchainMetadata: request.OnchainMetadata,
}
- if err := l.pluginORM.CreateRequest(newReq, pg.WithParentCtx(ctx)); err != nil {
+ if err := l.pluginORM.CreateRequest(ctx, newReq); err != nil {
if errors.Is(err, ErrDuplicateRequestID) {
l.logger.Warnw("handleOracleRequestV1: received a log with duplicate request ID", "requestID", formatRequestId(request.RequestId), "err", err)
} else {
@@ -395,7 +394,7 @@ func (l *functionsListener) handleRequest(ctx context.Context, requestID Request
requestIDStr := formatRequestId(requestID)
l.logger.Infow("processing request", "requestID", requestIDStr)
- eaClient, err := l.bridgeAccessor.NewExternalAdapterClient()
+ eaClient, err := l.bridgeAccessor.NewExternalAdapterClient(ctx)
if err != nil {
l.logger.Errorw("failed to create ExternalAdapterClient", "requestID", requestIDStr, "err", err)
l.setError(ctx, requestID, INTERNAL_ERROR, []byte(err.Error()))
@@ -450,7 +449,7 @@ func (l *functionsListener) handleRequest(ctx context.Context, requestID Request
promRequestComputationSuccess.WithLabelValues(l.contractAddressHex).Inc()
promComputationResultSize.WithLabelValues(l.contractAddressHex).Set(float64(len(computationResult)))
l.logger.Debugw("saving computation result", "requestID", requestIDStr)
- if err2 := l.pluginORM.SetResult(requestID, computationResult, time.Now(), pg.WithParentCtx(ctx)); err2 != nil {
+ if err2 := l.pluginORM.SetResult(ctx, requestID, computationResult, time.Now()); err2 != nil {
l.logger.Errorw("call to SetResult failed", "requestID", requestIDStr, "err", err2)
return err2
}
@@ -464,7 +463,7 @@ func (l *functionsListener) handleOracleResponseV1(response *evmrelayTypes.Oracl
ctx, cancel := l.getNewHandlerContext()
defer cancel()
- if err := l.pluginORM.SetConfirmed(response.RequestId, pg.WithParentCtx(ctx)); err != nil {
+ if err := l.pluginORM.SetConfirmed(ctx, response.RequestId); err != nil {
l.logger.Errorw("setting CONFIRMED state failed", "requestID", formatRequestId(response.RequestId), "err", err)
}
promRequestConfirmed.WithLabelValues(l.contractAddressHex).Inc()
@@ -486,7 +485,7 @@ func (l *functionsListener) timeoutRequests() {
case <-ticker.C:
cutoff := time.Now().Add(-(time.Duration(timeoutSec) * time.Second))
ctx, cancel := l.getNewHandlerContext()
- ids, err := l.pluginORM.TimeoutExpiredResults(cutoff, batchSize, pg.WithParentCtx(ctx))
+ ids, err := l.pluginORM.TimeoutExpiredResults(ctx, cutoff, batchSize)
cancel()
if err != nil {
l.logger.Errorw("error when calling FindExpiredResults", "err", err)
@@ -531,7 +530,7 @@ func (l *functionsListener) pruneRequests() {
case <-ticker.C:
ctx, cancel := l.getNewHandlerContext()
startTime := time.Now()
- nTotal, nPruned, err := l.pluginORM.PruneOldestRequests(maxStoredRequests, batchSize, pg.WithParentCtx(ctx))
+ nTotal, nPruned, err := l.pluginORM.PruneOldestRequests(ctx, maxStoredRequests, batchSize)
cancel()
elapsedMillis := time.Since(startTime).Milliseconds()
if err != nil {
diff --git a/core/services/functions/listener_test.go b/core/services/functions/listener_test.go
index 24d95cdcd6b..d6cd9aa23d6 100644
--- a/core/services/functions/listener_test.go
+++ b/core/services/functions/listener_test.go
@@ -1,6 +1,7 @@
package functions_test
import (
+ "context"
"encoding/json"
"errors"
"fmt"
@@ -35,7 +36,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config"
threshold_mocks "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/threshold/mocks"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types"
@@ -170,9 +170,9 @@ func TestFunctionsListener_HandleOracleRequestV1_Success(t *testing.T) {
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return([]types.OracleRequest{request}, nil, nil).Once()
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return(nil, nil, nil)
uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil)
- uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil)
+ uni.bridgeAccessor.On("NewExternalAdapterClient", mock.Anything).Return(uni.eaClient, nil)
uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Return(ResultBytes, nil, nil, nil)
- uni.pluginORM.On("SetResult", RequestID, ResultBytes, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ uni.pluginORM.On("SetResult", mock.Anything, RequestID, ResultBytes, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
close(doneCh)
}).Return(nil)
@@ -187,9 +187,9 @@ func TestFunctionsListener_HandleOffchainRequest_Success(t *testing.T) {
uni := NewFunctionsListenerUniverse(t, 0, 1_000_000)
uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil)
- uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil)
+ uni.bridgeAccessor.On("NewExternalAdapterClient", mock.Anything).Return(uni.eaClient, nil)
uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Return(ResultBytes, nil, nil, nil)
- uni.pluginORM.On("SetResult", RequestID, ResultBytes, mock.Anything, mock.Anything).Return(nil)
+ uni.pluginORM.On("SetResult", mock.Anything, RequestID, ResultBytes, mock.Anything, mock.Anything).Return(nil)
request := &functions_service.OffchainRequest{
RequestId: RequestID[:],
@@ -231,9 +231,9 @@ func TestFunctionsListener_HandleOffchainRequest_InternalError(t *testing.T) {
t.Parallel()
uni := NewFunctionsListenerUniverse(t, 0, 1_000_000)
uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil)
- uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil)
+ uni.bridgeAccessor.On("NewExternalAdapterClient", mock.Anything).Return(uni.eaClient, nil)
uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Return(nil, nil, nil, errors.New("error"))
- uni.pluginORM.On("SetError", RequestID, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
+ uni.pluginORM.On("SetError", mock.Anything, RequestID, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
request := &functions_service.OffchainRequest{
RequestId: RequestID[:],
@@ -264,9 +264,9 @@ func TestFunctionsListener_HandleOracleRequestV1_ComputationError(t *testing.T)
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return([]types.OracleRequest{request}, nil, nil).Once()
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return(nil, nil, nil)
uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil)
- uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil)
+ uni.bridgeAccessor.On("NewExternalAdapterClient", mock.Anything).Return(uni.eaClient, nil)
uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Return(nil, ErrorBytes, nil, nil)
- uni.pluginORM.On("SetError", RequestID, mock.Anything, ErrorBytes, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ uni.pluginORM.On("SetError", mock.Anything, RequestID, mock.Anything, ErrorBytes, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
close(doneCh)
}).Return(nil)
@@ -303,11 +303,11 @@ func TestFunctionsListener_HandleOracleRequestV1_ThresholdDecryptedSecrets(t *te
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return([]types.OracleRequest{request}, nil, nil).Once()
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return(nil, nil, nil)
uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil)
- uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil)
+ uni.bridgeAccessor.On("NewExternalAdapterClient", mock.Anything).Return(uni.eaClient, nil)
uni.eaClient.On("FetchEncryptedSecrets", mock.Anything, mock.Anything, RequestIDStr, mock.Anything, mock.Anything).Return(EncryptedSecrets, nil, nil)
uni.decryptor.On("Decrypt", mock.Anything, decryptionPlugin.CiphertextId(RequestID[:]), EncryptedSecrets).Return(DecryptedSecrets, nil)
uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Return(ResultBytes, nil, nil, nil)
- uni.pluginORM.On("SetResult", RequestID, ResultBytes, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ uni.pluginORM.On("SetResult", mock.Anything, RequestID, ResultBytes, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
close(doneCh)
}).Return(nil)
@@ -333,7 +333,7 @@ func TestFunctionsListener_HandleOracleRequestV1_CBORTooBig(t *testing.T) {
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return([]types.OracleRequest{request}, nil, nil).Once()
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return(nil, nil, nil)
uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil)
- uni.pluginORM.On("SetError", RequestID, functions_service.USER_ERROR, []byte("request too big (max 10 bytes)"), mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ uni.pluginORM.On("SetError", mock.Anything, RequestID, functions_service.USER_ERROR, []byte("request too big (max 10 bytes)"), mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
close(doneCh)
}).Return(nil)
@@ -359,9 +359,9 @@ func TestFunctionsListener_ReportSourceCodeDomains(t *testing.T) {
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return([]types.OracleRequest{request}, nil, nil).Once()
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return(nil, nil, nil)
uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil)
- uni.bridgeAccessor.On("NewExternalAdapterClient").Return(uni.eaClient, nil)
+ uni.bridgeAccessor.On("NewExternalAdapterClient", mock.Anything).Return(uni.eaClient, nil)
uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Return(ResultBytes, nil, Domains, nil)
- uni.pluginORM.On("SetResult", RequestID, ResultBytes, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ uni.pluginORM.On("SetResult", mock.Anything, RequestID, ResultBytes, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
close(doneCh)
}).Return(nil)
var sentMessage []byte
@@ -388,7 +388,7 @@ func TestFunctionsListener_PruneRequests(t *testing.T) {
uni := NewFunctionsListenerUniverse(t, 0, 1)
doneCh := make(chan bool)
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return(nil, nil, nil)
- uni.pluginORM.On("PruneOldestRequests", functions_service.DefaultPruneMaxStoredRequests, functions_service.DefaultPruneBatchSize, mock.Anything).Return(uint32(0), uint32(0), nil).Run(func(args mock.Arguments) {
+ uni.pluginORM.On("PruneOldestRequests", mock.Anything, functions_service.DefaultPruneMaxStoredRequests, functions_service.DefaultPruneBatchSize, mock.Anything).Return(uint32(0), uint32(0), nil).Run(func(args mock.Arguments) {
doneCh <- true
})
@@ -403,7 +403,7 @@ func TestFunctionsListener_TimeoutRequests(t *testing.T) {
uni := NewFunctionsListenerUniverse(t, 1, 0)
doneCh := make(chan bool)
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return(nil, nil, nil)
- uni.pluginORM.On("TimeoutExpiredResults", mock.Anything, uint32(1), mock.Anything).Return([]functions_service.RequestID{}, nil).Run(func(args mock.Arguments) {
+ uni.pluginORM.On("TimeoutExpiredResults", mock.Anything, mock.Anything, uint32(1), mock.Anything).Return([]functions_service.RequestID{}, nil).Run(func(args mock.Arguments) {
doneCh <- true
})
@@ -423,9 +423,7 @@ func TestFunctionsListener_ORMDoesNotFreezeHandlersForever(t *testing.T) {
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return([]types.OracleRequest{request}, nil, nil).Once()
uni.logPollerWrapper.On("LatestEvents", mock.Anything).Return(nil, nil, nil)
uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
- var queryerWrapper pg.Q
- args.Get(1).(pg.QOpt)(&queryerWrapper)
- <-queryerWrapper.ParentCtx.Done()
+ <-args.Get(0).(context.Context).Done()
ormCallExited.Done()
}).Return(errors.New("timeout"))
diff --git a/core/services/functions/mocks/bridge_accessor.go b/core/services/functions/mocks/bridge_accessor.go
index fa765287c44..4978da55d8b 100644
--- a/core/services/functions/mocks/bridge_accessor.go
+++ b/core/services/functions/mocks/bridge_accessor.go
@@ -3,6 +3,8 @@
package mocks
import (
+ context "context"
+
functions "github.com/smartcontractkit/chainlink/v2/core/services/functions"
mock "github.com/stretchr/testify/mock"
)
@@ -12,9 +14,9 @@ type BridgeAccessor struct {
mock.Mock
}
-// NewExternalAdapterClient provides a mock function with given fields:
-func (_m *BridgeAccessor) NewExternalAdapterClient() (functions.ExternalAdapterClient, error) {
- ret := _m.Called()
+// NewExternalAdapterClient provides a mock function with given fields: _a0
+func (_m *BridgeAccessor) NewExternalAdapterClient(_a0 context.Context) (functions.ExternalAdapterClient, error) {
+ ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for NewExternalAdapterClient")
@@ -22,19 +24,19 @@ func (_m *BridgeAccessor) NewExternalAdapterClient() (functions.ExternalAdapterC
var r0 functions.ExternalAdapterClient
var r1 error
- if rf, ok := ret.Get(0).(func() (functions.ExternalAdapterClient, error)); ok {
- return rf()
+ if rf, ok := ret.Get(0).(func(context.Context) (functions.ExternalAdapterClient, error)); ok {
+ return rf(_a0)
}
- if rf, ok := ret.Get(0).(func() functions.ExternalAdapterClient); ok {
- r0 = rf()
+ if rf, ok := ret.Get(0).(func(context.Context) functions.ExternalAdapterClient); ok {
+ r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(functions.ExternalAdapterClient)
}
}
- if rf, ok := ret.Get(1).(func() error); ok {
- r1 = rf()
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
diff --git a/core/services/functions/mocks/orm.go b/core/services/functions/mocks/orm.go
index 90055fe6286..ff72916171b 100644
--- a/core/services/functions/mocks/orm.go
+++ b/core/services/functions/mocks/orm.go
@@ -3,11 +3,11 @@
package mocks
import (
+ context "context"
+
functions "github.com/smartcontractkit/chainlink/v2/core/services/functions"
mock "github.com/stretchr/testify/mock"
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
-
time "time"
)
@@ -16,24 +16,17 @@ type ORM struct {
mock.Mock
}
-// CreateRequest provides a mock function with given fields: request, qopts
-func (_m *ORM) CreateRequest(request *functions.Request, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, request)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// CreateRequest provides a mock function with given fields: ctx, request
+func (_m *ORM) CreateRequest(ctx context.Context, request *functions.Request) error {
+ ret := _m.Called(ctx, request)
if len(ret) == 0 {
panic("no return value specified for CreateRequest")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*functions.Request, ...pg.QOpt) error); ok {
- r0 = rf(request, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *functions.Request) error); ok {
+ r0 = rf(ctx, request)
} else {
r0 = ret.Error(0)
}
@@ -41,16 +34,9 @@ func (_m *ORM) CreateRequest(request *functions.Request, qopts ...pg.QOpt) error
return r0
}
-// FindById provides a mock function with given fields: requestID, qopts
-func (_m *ORM) FindById(requestID functions.RequestID, qopts ...pg.QOpt) (*functions.Request, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, requestID)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// FindById provides a mock function with given fields: ctx, requestID
+func (_m *ORM) FindById(ctx context.Context, requestID functions.RequestID) (*functions.Request, error) {
+ ret := _m.Called(ctx, requestID)
if len(ret) == 0 {
panic("no return value specified for FindById")
@@ -58,19 +44,19 @@ func (_m *ORM) FindById(requestID functions.RequestID, qopts ...pg.QOpt) (*funct
var r0 *functions.Request
var r1 error
- if rf, ok := ret.Get(0).(func(functions.RequestID, ...pg.QOpt) (*functions.Request, error)); ok {
- return rf(requestID, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, functions.RequestID) (*functions.Request, error)); ok {
+ return rf(ctx, requestID)
}
- if rf, ok := ret.Get(0).(func(functions.RequestID, ...pg.QOpt) *functions.Request); ok {
- r0 = rf(requestID, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, functions.RequestID) *functions.Request); ok {
+ r0 = rf(ctx, requestID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*functions.Request)
}
}
- if rf, ok := ret.Get(1).(func(functions.RequestID, ...pg.QOpt) error); ok {
- r1 = rf(requestID, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, functions.RequestID) error); ok {
+ r1 = rf(ctx, requestID)
} else {
r1 = ret.Error(1)
}
@@ -78,16 +64,9 @@ func (_m *ORM) FindById(requestID functions.RequestID, qopts ...pg.QOpt) (*funct
return r0, r1
}
-// FindOldestEntriesByState provides a mock function with given fields: state, limit, qopts
-func (_m *ORM) FindOldestEntriesByState(state functions.RequestState, limit uint32, qopts ...pg.QOpt) ([]functions.Request, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, state, limit)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// FindOldestEntriesByState provides a mock function with given fields: ctx, state, limit
+func (_m *ORM) FindOldestEntriesByState(ctx context.Context, state functions.RequestState, limit uint32) ([]functions.Request, error) {
+ ret := _m.Called(ctx, state, limit)
if len(ret) == 0 {
panic("no return value specified for FindOldestEntriesByState")
@@ -95,19 +74,19 @@ func (_m *ORM) FindOldestEntriesByState(state functions.RequestState, limit uint
var r0 []functions.Request
var r1 error
- if rf, ok := ret.Get(0).(func(functions.RequestState, uint32, ...pg.QOpt) ([]functions.Request, error)); ok {
- return rf(state, limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, functions.RequestState, uint32) ([]functions.Request, error)); ok {
+ return rf(ctx, state, limit)
}
- if rf, ok := ret.Get(0).(func(functions.RequestState, uint32, ...pg.QOpt) []functions.Request); ok {
- r0 = rf(state, limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, functions.RequestState, uint32) []functions.Request); ok {
+ r0 = rf(ctx, state, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]functions.Request)
}
}
- if rf, ok := ret.Get(1).(func(functions.RequestState, uint32, ...pg.QOpt) error); ok {
- r1 = rf(state, limit, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, functions.RequestState, uint32) error); ok {
+ r1 = rf(ctx, state, limit)
} else {
r1 = ret.Error(1)
}
@@ -115,16 +94,9 @@ func (_m *ORM) FindOldestEntriesByState(state functions.RequestState, limit uint
return r0, r1
}
-// PruneOldestRequests provides a mock function with given fields: maxRequestsInDB, batchSize, qopts
-func (_m *ORM) PruneOldestRequests(maxRequestsInDB uint32, batchSize uint32, qopts ...pg.QOpt) (uint32, uint32, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, maxRequestsInDB, batchSize)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// PruneOldestRequests provides a mock function with given fields: ctx, maxRequestsInDB, batchSize
+func (_m *ORM) PruneOldestRequests(ctx context.Context, maxRequestsInDB uint32, batchSize uint32) (uint32, uint32, error) {
+ ret := _m.Called(ctx, maxRequestsInDB, batchSize)
if len(ret) == 0 {
panic("no return value specified for PruneOldestRequests")
@@ -133,23 +105,23 @@ func (_m *ORM) PruneOldestRequests(maxRequestsInDB uint32, batchSize uint32, qop
var r0 uint32
var r1 uint32
var r2 error
- if rf, ok := ret.Get(0).(func(uint32, uint32, ...pg.QOpt) (uint32, uint32, error)); ok {
- return rf(maxRequestsInDB, batchSize, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint32, uint32) (uint32, uint32, error)); ok {
+ return rf(ctx, maxRequestsInDB, batchSize)
}
- if rf, ok := ret.Get(0).(func(uint32, uint32, ...pg.QOpt) uint32); ok {
- r0 = rf(maxRequestsInDB, batchSize, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint32, uint32) uint32); ok {
+ r0 = rf(ctx, maxRequestsInDB, batchSize)
} else {
r0 = ret.Get(0).(uint32)
}
- if rf, ok := ret.Get(1).(func(uint32, uint32, ...pg.QOpt) uint32); ok {
- r1 = rf(maxRequestsInDB, batchSize, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, uint32, uint32) uint32); ok {
+ r1 = rf(ctx, maxRequestsInDB, batchSize)
} else {
r1 = ret.Get(1).(uint32)
}
- if rf, ok := ret.Get(2).(func(uint32, uint32, ...pg.QOpt) error); ok {
- r2 = rf(maxRequestsInDB, batchSize, qopts...)
+ if rf, ok := ret.Get(2).(func(context.Context, uint32, uint32) error); ok {
+ r2 = rf(ctx, maxRequestsInDB, batchSize)
} else {
r2 = ret.Error(2)
}
@@ -157,24 +129,17 @@ func (_m *ORM) PruneOldestRequests(maxRequestsInDB uint32, batchSize uint32, qop
return r0, r1, r2
}
-// SetConfirmed provides a mock function with given fields: requestID, qopts
-func (_m *ORM) SetConfirmed(requestID functions.RequestID, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, requestID)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// SetConfirmed provides a mock function with given fields: ctx, requestID
+func (_m *ORM) SetConfirmed(ctx context.Context, requestID functions.RequestID) error {
+ ret := _m.Called(ctx, requestID)
if len(ret) == 0 {
panic("no return value specified for SetConfirmed")
}
var r0 error
- if rf, ok := ret.Get(0).(func(functions.RequestID, ...pg.QOpt) error); ok {
- r0 = rf(requestID, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, functions.RequestID) error); ok {
+ r0 = rf(ctx, requestID)
} else {
r0 = ret.Error(0)
}
@@ -182,24 +147,17 @@ func (_m *ORM) SetConfirmed(requestID functions.RequestID, qopts ...pg.QOpt) err
return r0
}
-// SetError provides a mock function with given fields: requestID, errorType, computationError, readyAt, readyForProcessing, qopts
-func (_m *ORM) SetError(requestID functions.RequestID, errorType functions.ErrType, computationError []byte, readyAt time.Time, readyForProcessing bool, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, requestID, errorType, computationError, readyAt, readyForProcessing)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// SetError provides a mock function with given fields: ctx, requestID, errorType, computationError, readyAt, readyForProcessing
+func (_m *ORM) SetError(ctx context.Context, requestID functions.RequestID, errorType functions.ErrType, computationError []byte, readyAt time.Time, readyForProcessing bool) error {
+ ret := _m.Called(ctx, requestID, errorType, computationError, readyAt, readyForProcessing)
if len(ret) == 0 {
panic("no return value specified for SetError")
}
var r0 error
- if rf, ok := ret.Get(0).(func(functions.RequestID, functions.ErrType, []byte, time.Time, bool, ...pg.QOpt) error); ok {
- r0 = rf(requestID, errorType, computationError, readyAt, readyForProcessing, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, functions.RequestID, functions.ErrType, []byte, time.Time, bool) error); ok {
+ r0 = rf(ctx, requestID, errorType, computationError, readyAt, readyForProcessing)
} else {
r0 = ret.Error(0)
}
@@ -207,24 +165,17 @@ func (_m *ORM) SetError(requestID functions.RequestID, errorType functions.ErrTy
return r0
}
-// SetFinalized provides a mock function with given fields: requestID, reportedResult, reportedError, qopts
-func (_m *ORM) SetFinalized(requestID functions.RequestID, reportedResult []byte, reportedError []byte, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, requestID, reportedResult, reportedError)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// SetFinalized provides a mock function with given fields: ctx, requestID, reportedResult, reportedError
+func (_m *ORM) SetFinalized(ctx context.Context, requestID functions.RequestID, reportedResult []byte, reportedError []byte) error {
+ ret := _m.Called(ctx, requestID, reportedResult, reportedError)
if len(ret) == 0 {
panic("no return value specified for SetFinalized")
}
var r0 error
- if rf, ok := ret.Get(0).(func(functions.RequestID, []byte, []byte, ...pg.QOpt) error); ok {
- r0 = rf(requestID, reportedResult, reportedError, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, functions.RequestID, []byte, []byte) error); ok {
+ r0 = rf(ctx, requestID, reportedResult, reportedError)
} else {
r0 = ret.Error(0)
}
@@ -232,24 +183,17 @@ func (_m *ORM) SetFinalized(requestID functions.RequestID, reportedResult []byte
return r0
}
-// SetResult provides a mock function with given fields: requestID, computationResult, readyAt, qopts
-func (_m *ORM) SetResult(requestID functions.RequestID, computationResult []byte, readyAt time.Time, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, requestID, computationResult, readyAt)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// SetResult provides a mock function with given fields: ctx, requestID, computationResult, readyAt
+func (_m *ORM) SetResult(ctx context.Context, requestID functions.RequestID, computationResult []byte, readyAt time.Time) error {
+ ret := _m.Called(ctx, requestID, computationResult, readyAt)
if len(ret) == 0 {
panic("no return value specified for SetResult")
}
var r0 error
- if rf, ok := ret.Get(0).(func(functions.RequestID, []byte, time.Time, ...pg.QOpt) error); ok {
- r0 = rf(requestID, computationResult, readyAt, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, functions.RequestID, []byte, time.Time) error); ok {
+ r0 = rf(ctx, requestID, computationResult, readyAt)
} else {
r0 = ret.Error(0)
}
@@ -257,16 +201,9 @@ func (_m *ORM) SetResult(requestID functions.RequestID, computationResult []byte
return r0
}
-// TimeoutExpiredResults provides a mock function with given fields: cutoff, limit, qopts
-func (_m *ORM) TimeoutExpiredResults(cutoff time.Time, limit uint32, qopts ...pg.QOpt) ([]functions.RequestID, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, cutoff, limit)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// TimeoutExpiredResults provides a mock function with given fields: ctx, cutoff, limit
+func (_m *ORM) TimeoutExpiredResults(ctx context.Context, cutoff time.Time, limit uint32) ([]functions.RequestID, error) {
+ ret := _m.Called(ctx, cutoff, limit)
if len(ret) == 0 {
panic("no return value specified for TimeoutExpiredResults")
@@ -274,19 +211,19 @@ func (_m *ORM) TimeoutExpiredResults(cutoff time.Time, limit uint32, qopts ...pg
var r0 []functions.RequestID
var r1 error
- if rf, ok := ret.Get(0).(func(time.Time, uint32, ...pg.QOpt) ([]functions.RequestID, error)); ok {
- return rf(cutoff, limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, time.Time, uint32) ([]functions.RequestID, error)); ok {
+ return rf(ctx, cutoff, limit)
}
- if rf, ok := ret.Get(0).(func(time.Time, uint32, ...pg.QOpt) []functions.RequestID); ok {
- r0 = rf(cutoff, limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, time.Time, uint32) []functions.RequestID); ok {
+ r0 = rf(ctx, cutoff, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]functions.RequestID)
}
}
- if rf, ok := ret.Get(1).(func(time.Time, uint32, ...pg.QOpt) error); ok {
- r1 = rf(cutoff, limit, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, time.Time, uint32) error); ok {
+ r1 = rf(ctx, cutoff, limit)
} else {
r1 = ret.Error(1)
}
diff --git a/core/services/functions/orm.go b/core/services/functions/orm.go
index 7838c700858..f45effa9354 100644
--- a/core/services/functions/orm.go
+++ b/core/services/functions/orm.go
@@ -1,38 +1,37 @@
package functions
import (
+ "context"
"fmt"
"time"
"github.com/ethereum/go-ethereum/common"
- "github.com/pkg/errors"
-
"github.com/jmoiron/sqlx"
+ "github.com/pkg/errors"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
)
//go:generate mockery --quiet --name ORM --output ./mocks/ --case=underscore
type ORM interface {
- CreateRequest(request *Request, qopts ...pg.QOpt) error
+ CreateRequest(ctx context.Context, request *Request) error
- SetResult(requestID RequestID, computationResult []byte, readyAt time.Time, qopts ...pg.QOpt) error
- SetError(requestID RequestID, errorType ErrType, computationError []byte, readyAt time.Time, readyForProcessing bool, qopts ...pg.QOpt) error
- SetFinalized(requestID RequestID, reportedResult []byte, reportedError []byte, qopts ...pg.QOpt) error
- SetConfirmed(requestID RequestID, qopts ...pg.QOpt) error
+ SetResult(ctx context.Context, requestID RequestID, computationResult []byte, readyAt time.Time) error
+ SetError(ctx context.Context, requestID RequestID, errorType ErrType, computationError []byte, readyAt time.Time, readyForProcessing bool) error
+ SetFinalized(ctx context.Context, requestID RequestID, reportedResult []byte, reportedError []byte) error
+ SetConfirmed(ctx context.Context, requestID RequestID) error
- TimeoutExpiredResults(cutoff time.Time, limit uint32, qopts ...pg.QOpt) ([]RequestID, error)
+ TimeoutExpiredResults(ctx context.Context, cutoff time.Time, limit uint32) ([]RequestID, error)
- FindOldestEntriesByState(state RequestState, limit uint32, qopts ...pg.QOpt) ([]Request, error)
- FindById(requestID RequestID, qopts ...pg.QOpt) (*Request, error)
+ FindOldestEntriesByState(ctx context.Context, state RequestState, limit uint32) ([]Request, error)
+ FindById(ctx context.Context, requestID RequestID) (*Request, error)
- PruneOldestRequests(maxRequestsInDB uint32, batchSize uint32, qopts ...pg.QOpt) (total uint32, pruned uint32, err error)
+ PruneOldestRequests(ctx context.Context, maxRequestsInDB uint32, batchSize uint32) (total uint32, pruned uint32, err error)
}
type orm struct {
- q pg.Q
+ ds sqlutil.DataSource
contractAddress common.Address
}
@@ -49,19 +48,20 @@ const (
"callback_gas_limit, coordinator_contract_address, onchain_metadata, processing_metadata"
)
-func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, contractAddress common.Address) ORM {
+func NewORM(ds sqlutil.DataSource, contractAddress common.Address) ORM {
return &orm{
- q: pg.NewQ(db, lggr, cfg),
+ ds: ds,
contractAddress: contractAddress,
}
}
-func (o *orm) CreateRequest(request *Request, qopts ...pg.QOpt) error {
+func (o *orm) CreateRequest(ctx context.Context, request *Request) error {
stmt := fmt.Sprintf(`
INSERT INTO %s (request_id, contract_address, received_at, request_tx_hash, state, flags, aggregation_method, callback_gas_limit, coordinator_contract_address, onchain_metadata)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10) ON CONFLICT (request_id) DO NOTHING;
`, tableName)
- result, err := o.q.WithOpts(qopts...).Exec(
+ result, err := o.ds.ExecContext(
+ ctx,
stmt,
request.RequestID,
o.contractAddress,
@@ -86,11 +86,11 @@ func (o *orm) CreateRequest(request *Request, qopts ...pg.QOpt) error {
return nil
}
-func (o *orm) setWithStateTransitionCheck(requestID RequestID, newState RequestState, setter func(pg.Queryer) error, qopts ...pg.QOpt) error {
- err := o.q.WithOpts(qopts...).Transaction(func(tx pg.Queryer) error {
+func (o *orm) setWithStateTransitionCheck(ctx context.Context, requestID RequestID, newState RequestState, setter func(sqlutil.DataSource) error) error {
+ err := sqlutil.TransactDataSource(ctx, o.ds, nil, func(tx sqlutil.DataSource) error {
prevState := defaultInitialState
stmt := fmt.Sprintf(`SELECT state FROM %s WHERE request_id=$1 AND contract_address=$2;`, tableName)
- if err2 := tx.Get(&prevState, stmt, requestID, o.contractAddress); err2 != nil {
+ if err2 := tx.GetContext(ctx, &prevState, stmt, requestID, o.contractAddress); err2 != nil {
return err2
}
if err2 := CheckStateTransition(prevState, newState); err2 != nil {
@@ -102,64 +102,64 @@ func (o *orm) setWithStateTransitionCheck(requestID RequestID, newState RequestS
return err
}
-func (o *orm) SetResult(requestID RequestID, computationResult []byte, readyAt time.Time, qopts ...pg.QOpt) error {
+func (o *orm) SetResult(ctx context.Context, requestID RequestID, computationResult []byte, readyAt time.Time) error {
newState := RESULT_READY
- err := o.setWithStateTransitionCheck(requestID, newState, func(tx pg.Queryer) error {
+ err := o.setWithStateTransitionCheck(ctx, requestID, newState, func(tx sqlutil.DataSource) error {
stmt := fmt.Sprintf(`
UPDATE %s
SET result=$3, result_ready_at=$4, state=$5
WHERE request_id=$1 AND contract_address=$2;
`, tableName)
- _, err2 := tx.Exec(stmt, requestID, o.contractAddress, computationResult, readyAt, newState)
+ _, err2 := tx.ExecContext(ctx, stmt, requestID, o.contractAddress, computationResult, readyAt, newState)
return err2
- }, qopts...)
+ })
return err
}
-func (o *orm) SetError(requestID RequestID, errorType ErrType, computationError []byte, readyAt time.Time, readyForProcessing bool, qopts ...pg.QOpt) error {
+func (o *orm) SetError(ctx context.Context, requestID RequestID, errorType ErrType, computationError []byte, readyAt time.Time, readyForProcessing bool) error {
var newState RequestState
if readyForProcessing {
newState = RESULT_READY
} else {
newState = IN_PROGRESS
}
- err := o.setWithStateTransitionCheck(requestID, newState, func(tx pg.Queryer) error {
+ err := o.setWithStateTransitionCheck(ctx, requestID, newState, func(tx sqlutil.DataSource) error {
stmt := fmt.Sprintf(`
UPDATE %s
SET error=$3, error_type=$4, result_ready_at=$5, state=$6
WHERE request_id=$1 AND contract_address=$2;
`, tableName)
- _, err2 := tx.Exec(stmt, requestID, o.contractAddress, computationError, errorType, readyAt, newState)
+ _, err2 := tx.ExecContext(ctx, stmt, requestID, o.contractAddress, computationError, errorType, readyAt, newState)
return err2
- }, qopts...)
+ })
return err
}
-func (o *orm) SetFinalized(requestID RequestID, reportedResult []byte, reportedError []byte, qopts ...pg.QOpt) error {
+func (o *orm) SetFinalized(ctx context.Context, requestID RequestID, reportedResult []byte, reportedError []byte) error {
newState := FINALIZED
- err := o.setWithStateTransitionCheck(requestID, newState, func(tx pg.Queryer) error {
+ err := o.setWithStateTransitionCheck(ctx, requestID, newState, func(tx sqlutil.DataSource) error {
stmt := fmt.Sprintf(`
UPDATE %s
SET transmitted_result=$3, transmitted_error=$4, state=$5
WHERE request_id=$1 AND contract_address=$2;
`, tableName)
- _, err2 := tx.Exec(stmt, requestID, o.contractAddress, reportedResult, reportedError, newState)
+ _, err2 := tx.ExecContext(ctx, stmt, requestID, o.contractAddress, reportedResult, reportedError, newState)
return err2
- }, qopts...)
+ })
return err
}
-func (o *orm) SetConfirmed(requestID RequestID, qopts ...pg.QOpt) error {
+func (o *orm) SetConfirmed(ctx context.Context, requestID RequestID) error {
newState := CONFIRMED
- err := o.setWithStateTransitionCheck(requestID, newState, func(tx pg.Queryer) error {
+ err := o.setWithStateTransitionCheck(ctx, requestID, newState, func(tx sqlutil.DataSource) error {
stmt := fmt.Sprintf(`UPDATE %s SET state=$3 WHERE request_id=$1 AND contract_address=$2;`, tableName)
- _, err2 := tx.Exec(stmt, requestID, o.contractAddress, newState)
+ _, err2 := tx.ExecContext(ctx, stmt, requestID, o.contractAddress, newState)
return err2
- }, qopts...)
+ })
return err
}
-func (o *orm) TimeoutExpiredResults(cutoff time.Time, limit uint32, qopts ...pg.QOpt) ([]RequestID, error) {
+func (o *orm) TimeoutExpiredResults(ctx context.Context, cutoff time.Time, limit uint32) ([]RequestID, error) {
var ids []RequestID
allowedPrevStates := []RequestState{IN_PROGRESS, RESULT_READY, FINALIZED}
nextState := TIMED_OUT
@@ -169,14 +169,14 @@ func (o *orm) TimeoutExpiredResults(cutoff time.Time, limit uint32, qopts ...pg.
return ids, err
}
}
- err := o.q.WithOpts(qopts...).Transaction(func(tx pg.Queryer) error {
+ err := sqlutil.TransactDataSource(ctx, o.ds, nil, func(tx sqlutil.DataSource) error {
selectStmt := fmt.Sprintf(`
SELECT request_id
FROM %s
WHERE (state=$1 OR state=$2 OR state=$3) AND contract_address=$4 AND received_at < ($5)
ORDER BY received_at
LIMIT $6;`, tableName)
- if err2 := tx.Select(&ids, selectStmt, allowedPrevStates[0], allowedPrevStates[1], allowedPrevStates[2], o.contractAddress, cutoff, limit); err2 != nil {
+ if err2 := tx.SelectContext(ctx, &ids, selectStmt, allowedPrevStates[0], allowedPrevStates[1], allowedPrevStates[2], o.contractAddress, cutoff, limit); err2 != nil {
return err2
}
if len(ids) == 0 {
@@ -200,7 +200,7 @@ func (o *orm) TimeoutExpiredResults(cutoff time.Time, limit uint32, qopts ...pg.
return err2
}
updateStmt = tx.Rebind(updateStmt)
- if _, err2 := tx.Exec(updateStmt, args...); err2 != nil {
+ if _, err2 := tx.ExecContext(ctx, updateStmt, args...); err2 != nil {
return err2
}
return nil
@@ -209,28 +209,28 @@ func (o *orm) TimeoutExpiredResults(cutoff time.Time, limit uint32, qopts ...pg.
return ids, err
}
-func (o *orm) FindOldestEntriesByState(state RequestState, limit uint32, qopts ...pg.QOpt) ([]Request, error) {
+func (o *orm) FindOldestEntriesByState(ctx context.Context, state RequestState, limit uint32) ([]Request, error) {
var requests []Request
stmt := fmt.Sprintf(`SELECT %s FROM %s WHERE state=$1 AND contract_address=$2 ORDER BY received_at LIMIT $3;`, requestFields, tableName)
- if err := o.q.WithOpts(qopts...).Select(&requests, stmt, state, o.contractAddress, limit); err != nil {
+ if err := o.ds.SelectContext(ctx, &requests, stmt, state, o.contractAddress, limit); err != nil {
return nil, err
}
return requests, nil
}
-func (o *orm) FindById(requestID RequestID, qopts ...pg.QOpt) (*Request, error) {
+func (o *orm) FindById(ctx context.Context, requestID RequestID) (*Request, error) {
var request Request
stmt := fmt.Sprintf(`SELECT %s FROM %s WHERE request_id=$1 AND contract_address=$2;`, requestFields, tableName)
- if err := o.q.WithOpts(qopts...).Get(&request, stmt, requestID, o.contractAddress); err != nil {
+ if err := o.ds.GetContext(ctx, &request, stmt, requestID, o.contractAddress); err != nil {
return nil, err
}
return &request, nil
}
-func (o *orm) PruneOldestRequests(maxStoredRequests uint32, batchSize uint32, qopts ...pg.QOpt) (total uint32, pruned uint32, err error) {
- err = o.q.WithOpts(qopts...).Transaction(func(tx pg.Queryer) error {
+func (o *orm) PruneOldestRequests(ctx context.Context, maxStoredRequests uint32, batchSize uint32) (total uint32, pruned uint32, err error) {
+ err = sqlutil.TransactDataSource(ctx, o.ds, nil, func(tx sqlutil.DataSource) error {
stmt := fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE contract_address=$1`, tableName)
- if err2 := tx.Get(&total, stmt, o.contractAddress); err2 != nil {
+ if err2 := tx.GetContext(ctx, &total, stmt, o.contractAddress); err2 != nil {
return errors.Wrap(err, "failed to get request count")
}
@@ -246,7 +246,7 @@ func (o *orm) PruneOldestRequests(maxStoredRequests uint32, batchSize uint32, qo
with := fmt.Sprintf(`WITH ids AS (SELECT request_id FROM %s WHERE contract_address = $1 ORDER BY received_at LIMIT $2)`, tableName)
deleteStmt := fmt.Sprintf(`%s DELETE FROM %s WHERE contract_address = $1 AND request_id IN (SELECT request_id FROM ids);`, with, tableName)
- res, err2 := tx.Exec(deleteStmt, o.contractAddress, pruneLimit)
+ res, err2 := tx.ExecContext(ctx, deleteStmt, o.contractAddress, pruneLimit)
if err2 != nil {
return err2
}
diff --git a/core/services/functions/orm_test.go b/core/services/functions/orm_test.go
index ca92aafcb0e..37b3a28256f 100644
--- a/core/services/functions/orm_test.go
+++ b/core/services/functions/orm_test.go
@@ -11,7 +11,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/functions"
)
@@ -28,9 +27,8 @@ func setupORM(t *testing.T) functions.ORM {
var (
db = pgtest.NewSqlxDB(t)
- lggr = logger.TestLogger(t)
contract = testutils.NewAddress()
- orm = functions.NewORM(db, lggr, pgtest.NewQConfig(true), contract)
+ orm = functions.NewORM(db, contract)
)
return orm
@@ -47,6 +45,7 @@ func createRequest(t *testing.T, orm functions.ORM) (functions.RequestID, common
}
func createRequestWithTimestamp(t *testing.T, orm functions.ORM, ts time.Time) (functions.RequestID, common.Hash) {
+ ctx := testutils.Context(t)
id := newRequestID()
txHash := utils.RandomHash()
newReq := &functions.Request{
@@ -59,19 +58,20 @@ func createRequestWithTimestamp(t *testing.T, orm functions.ORM, ts time.Time) (
CoordinatorContractAddress: &defaultCoordinatorContract,
OnchainMetadata: defaultMetadata,
}
- err := orm.CreateRequest(newReq)
+ err := orm.CreateRequest(ctx, newReq)
require.NoError(t, err)
return id, txHash
}
func TestORM_CreateRequestsAndFindByID(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
id1, txHash1, ts1 := createRequest(t, orm)
id2, txHash2, ts2 := createRequest(t, orm)
- req1, err := orm.FindById(id1)
+ req1, err := orm.FindById(ctx, id1)
require.NoError(t, err)
require.Equal(t, id1, req1.RequestID)
require.Equal(t, &txHash1, req1.RequestTxHash)
@@ -83,7 +83,7 @@ func TestORM_CreateRequestsAndFindByID(t *testing.T) {
require.Equal(t, defaultCoordinatorContract, *req1.CoordinatorContractAddress)
require.Equal(t, defaultMetadata, req1.OnchainMetadata)
- req2, err := orm.FindById(id2)
+ req2, err := orm.FindById(ctx, id2)
require.NoError(t, err)
require.Equal(t, id2, req2.RequestID)
require.Equal(t, &txHash2, req2.RequestTxHash)
@@ -91,14 +91,14 @@ func TestORM_CreateRequestsAndFindByID(t *testing.T) {
require.Equal(t, functions.IN_PROGRESS, req2.State)
t.Run("missing ID", func(t *testing.T) {
- req, err := orm.FindById(newRequestID())
+ req, err := orm.FindById(testutils.Context(t), newRequestID())
require.Error(t, err)
require.Nil(t, req)
})
t.Run("duplicated", func(t *testing.T) {
newReq := &functions.Request{RequestID: id1, RequestTxHash: &txHash1, ReceivedAt: ts1}
- err := orm.CreateRequest(newReq)
+ err := orm.CreateRequest(testutils.Context(t), newReq)
require.Error(t, err)
require.True(t, errors.Is(err, functions.ErrDuplicateRequestID))
})
@@ -106,15 +106,16 @@ func TestORM_CreateRequestsAndFindByID(t *testing.T) {
func TestORM_SetResult(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
id, _, ts := createRequest(t, orm)
rdts := time.Now().Round(time.Second)
- err := orm.SetResult(id, []byte("result"), rdts)
+ err := orm.SetResult(ctx, id, []byte("result"), rdts)
require.NoError(t, err)
- req, err := orm.FindById(id)
+ req, err := orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, id, req.RequestID)
require.Equal(t, ts, req.ReceivedAt)
@@ -126,15 +127,16 @@ func TestORM_SetResult(t *testing.T) {
func TestORM_SetError(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
id, _, ts := createRequest(t, orm)
rdts := time.Now().Round(time.Second)
- err := orm.SetError(id, functions.USER_ERROR, []byte("error"), rdts, true)
+ err := orm.SetError(ctx, id, functions.USER_ERROR, []byte("error"), rdts, true)
require.NoError(t, err)
- req, err := orm.FindById(id)
+ req, err := orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, id, req.RequestID)
require.Equal(t, ts, req.ReceivedAt)
@@ -148,15 +150,16 @@ func TestORM_SetError(t *testing.T) {
func TestORM_SetError_Internal(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
id, _, ts := createRequest(t, orm)
rdts := time.Now().Round(time.Second)
- err := orm.SetError(id, functions.INTERNAL_ERROR, []byte("error"), rdts, false)
+ err := orm.SetError(ctx, id, functions.INTERNAL_ERROR, []byte("error"), rdts, false)
require.NoError(t, err)
- req, err := orm.FindById(id)
+ req, err := orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, id, req.RequestID)
require.Equal(t, ts, req.ReceivedAt)
@@ -167,14 +170,15 @@ func TestORM_SetError_Internal(t *testing.T) {
func TestORM_SetFinalized(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
id, _, _ := createRequest(t, orm)
- err := orm.SetFinalized(id, []byte("result"), []byte("error"))
+ err := orm.SetFinalized(ctx, id, []byte("result"), []byte("error"))
require.NoError(t, err)
- req, err := orm.FindById(id)
+ req, err := orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, []byte("result"), req.TransmittedResult)
require.Equal(t, []byte("error"), req.TransmittedError)
@@ -183,49 +187,51 @@ func TestORM_SetFinalized(t *testing.T) {
func TestORM_SetConfirmed(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
id, _, _ := createRequest(t, orm)
- err := orm.SetConfirmed(id)
+ err := orm.SetConfirmed(ctx, id)
require.NoError(t, err)
- req, err := orm.FindById(id)
+ req, err := orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, functions.CONFIRMED, req.State)
}
func TestORM_StateTransitions(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
now := time.Now()
id, _ := createRequestWithTimestamp(t, orm, now)
- req, err := orm.FindById(id)
+ req, err := orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, functions.IN_PROGRESS, req.State)
- err = orm.SetResult(id, []byte{}, now)
+ err = orm.SetResult(ctx, id, []byte{}, now)
require.NoError(t, err)
- req, err = orm.FindById(id)
+ req, err = orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, functions.RESULT_READY, req.State)
- _, err = orm.TimeoutExpiredResults(now.Add(time.Minute), 1)
+ _, err = orm.TimeoutExpiredResults(ctx, now.Add(time.Minute), 1)
require.NoError(t, err)
- req, err = orm.FindById(id)
+ req, err = orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, functions.TIMED_OUT, req.State)
- err = orm.SetFinalized(id, nil, nil)
+ err = orm.SetFinalized(ctx, id, nil, nil)
require.Error(t, err)
- req, err = orm.FindById(id)
+ req, err = orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, functions.TIMED_OUT, req.State)
- err = orm.SetConfirmed(id)
+ err = orm.SetConfirmed(ctx, id)
require.NoError(t, err)
- req, err = orm.FindById(id)
+ req, err = orm.FindById(ctx, id)
require.NoError(t, err)
require.Equal(t, functions.CONFIRMED, req.State)
}
@@ -240,7 +246,8 @@ func TestORM_FindOldestEntriesByState(t *testing.T) {
id1, _ := createRequestWithTimestamp(t, orm, now.Add(1*time.Minute))
t.Run("with limit", func(t *testing.T) {
- result, err := orm.FindOldestEntriesByState(functions.IN_PROGRESS, 2)
+ ctx := testutils.Context(t)
+ result, err := orm.FindOldestEntriesByState(ctx, functions.IN_PROGRESS, 2)
require.NoError(t, err)
require.Equal(t, 2, len(result), "incorrect results length")
require.Equal(t, id1, result[0].RequestID, "incorrect results order")
@@ -255,13 +262,15 @@ func TestORM_FindOldestEntriesByState(t *testing.T) {
})
t.Run("with no limit", func(t *testing.T) {
- result, err := orm.FindOldestEntriesByState(functions.IN_PROGRESS, 20)
+ ctx := testutils.Context(t)
+ result, err := orm.FindOldestEntriesByState(ctx, functions.IN_PROGRESS, 20)
require.NoError(t, err)
require.Equal(t, 3, len(result), "incorrect results length")
})
t.Run("no matching entries", func(t *testing.T) {
- result, err := orm.FindOldestEntriesByState(functions.RESULT_READY, 10)
+ ctx := testutils.Context(t)
+ result, err := orm.FindOldestEntriesByState(ctx, functions.RESULT_READY, 10)
require.NoError(t, err)
require.Equal(t, 0, len(result), "incorrect results length")
})
@@ -269,6 +278,7 @@ func TestORM_FindOldestEntriesByState(t *testing.T) {
func TestORM_TimeoutExpiredResults(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
now := time.Now()
@@ -278,26 +288,26 @@ func TestORM_TimeoutExpiredResults(t *testing.T) {
ids = append(ids, id)
}
// can time out IN_PROGRESS, RESULT_READY or FINALIZED
- err := orm.SetResult(ids[0], []byte("result"), now)
+ err := orm.SetResult(ctx, ids[0], []byte("result"), now)
require.NoError(t, err)
- err = orm.SetFinalized(ids[1], []byte("result"), []byte(""))
+ err = orm.SetFinalized(ctx, ids[1], []byte("result"), []byte(""))
require.NoError(t, err)
// can't time out CONFIRMED
- err = orm.SetConfirmed(ids[2])
+ err = orm.SetConfirmed(ctx, ids[2])
require.NoError(t, err)
- results, err := orm.TimeoutExpiredResults(now.Add(-35*time.Minute), 1)
+ results, err := orm.TimeoutExpiredResults(ctx, now.Add(-35*time.Minute), 1)
require.NoError(t, err)
require.Equal(t, 1, len(results), "not respecting limit")
require.Equal(t, ids[0], results[0], "incorrect results order")
- results, err = orm.TimeoutExpiredResults(now.Add(-15*time.Minute), 10)
+ results, err = orm.TimeoutExpiredResults(ctx, now.Add(-15*time.Minute), 10)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, ids[1], results[0], "incorrect results order")
require.Equal(t, ids[3], results[1], "incorrect results order")
- results, err = orm.TimeoutExpiredResults(now.Add(-15*time.Minute), 10)
+ results, err = orm.TimeoutExpiredResults(ctx, now.Add(-15*time.Minute), 10)
require.NoError(t, err)
require.Equal(t, 0, len(results), "not idempotent")
@@ -309,7 +319,7 @@ func TestORM_TimeoutExpiredResults(t *testing.T) {
functions.IN_PROGRESS,
}
for i, expectedState := range expectedFinalStates {
- req, err := orm.FindById(ids[i])
+ req, err := orm.FindById(ctx, ids[i])
require.NoError(t, err)
require.Equal(t, req.State, expectedState, "incorrect state")
}
@@ -317,6 +327,7 @@ func TestORM_TimeoutExpiredResults(t *testing.T) {
func TestORM_PruneOldestRequests(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
now := time.Now()
@@ -328,31 +339,31 @@ func TestORM_PruneOldestRequests(t *testing.T) {
}
// don't prune if max not hit
- total, pruned, err := orm.PruneOldestRequests(6, 3)
+ total, pruned, err := orm.PruneOldestRequests(ctx, 6, 3)
require.NoError(t, err)
require.Equal(t, uint32(5), total)
require.Equal(t, uint32(0), pruned)
// prune up to max batch size
- total, pruned, err = orm.PruneOldestRequests(1, 2)
+ total, pruned, err = orm.PruneOldestRequests(ctx, 1, 2)
require.NoError(t, err)
require.Equal(t, uint32(5), total)
require.Equal(t, uint32(2), pruned)
// prune all above the limit
- total, pruned, err = orm.PruneOldestRequests(1, 20)
+ total, pruned, err = orm.PruneOldestRequests(ctx, 1, 20)
require.NoError(t, err)
require.Equal(t, uint32(3), total)
require.Equal(t, uint32(2), pruned)
// no pruning needed any more
- total, pruned, err = orm.PruneOldestRequests(1, 20)
+ total, pruned, err = orm.PruneOldestRequests(ctx, 1, 20)
require.NoError(t, err)
require.Equal(t, uint32(1), total)
require.Equal(t, uint32(0), pruned)
// verify only the newest one is left after pruning
- result, err := orm.FindOldestEntriesByState(functions.IN_PROGRESS, 20)
+ result, err := orm.FindOldestEntriesByState(ctx, functions.IN_PROGRESS, 20)
require.NoError(t, err)
require.Equal(t, 1, len(result), "incorrect results length")
require.Equal(t, ids[4], result[0].RequestID, "incorrect results order")
@@ -360,6 +371,7 @@ func TestORM_PruneOldestRequests(t *testing.T) {
func TestORM_PruneOldestRequests_Large(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t)
now := time.Now()
@@ -369,13 +381,13 @@ func TestORM_PruneOldestRequests_Large(t *testing.T) {
}
// prune 900/1000
- total, pruned, err := orm.PruneOldestRequests(100, 1000)
+ total, pruned, err := orm.PruneOldestRequests(ctx, 100, 1000)
require.NoError(t, err)
require.Equal(t, uint32(1000), total)
require.Equal(t, uint32(900), pruned)
// verify there's 100 left
- result, err := orm.FindOldestEntriesByState(functions.IN_PROGRESS, 200)
+ result, err := orm.FindOldestEntriesByState(ctx, functions.IN_PROGRESS, 200)
require.NoError(t, err)
require.Equal(t, 100, len(result), "incorrect results length")
}
diff --git a/core/services/gateway/delegate.go b/core/services/gateway/delegate.go
index ba34f2894de..8cddc027803 100644
--- a/core/services/gateway/delegate.go
+++ b/core/services/gateway/delegate.go
@@ -41,10 +41,10 @@ func (d *Delegate) JobType() job.Type {
return job.Gateway
}
-func (d *Delegate) BeforeJobCreated(spec job.Job) {}
-func (d *Delegate) AfterJobCreated(spec job.Job) {}
-func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) BeforeJobCreated(spec job.Job) {}
+func (d *Delegate) AfterJobCreated(spec job.Job) {}
+func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec returns the scheduler to be used for running observer jobs
func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services []job.ServiceCtx, err error) {
diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist.go b/core/services/gateway/handlers/functions/allowlist/allowlist.go
index 020de2359c2..f0fe5c8c829 100644
--- a/core/services/gateway/handlers/functions/allowlist/allowlist.go
+++ b/core/services/gateway/handlers/functions/allowlist/allowlist.go
@@ -128,7 +128,7 @@ func (a *onchainAllowlist) Start(ctx context.Context) error {
return nil
}
- a.loadStoredAllowedSenderList()
+ a.loadStoredAllowedSenderList(ctx)
updateOnce := func() {
timeoutCtx, cancel := utils.ContextFromChanWithTimeout(a.stopCh, time.Duration(a.config.UpdateTimeoutSec)*time.Second)
@@ -245,12 +245,12 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b
return errors.Wrap(err, "error calling GetAllAllowedSenders")
}
- err = a.orm.PurgeAllowedSenders()
+ err = a.orm.PurgeAllowedSenders(ctx)
if err != nil {
a.lggr.Errorf("failed to purge allowedSenderList: %w", err)
}
- err = a.orm.CreateAllowedSenders(allowedSenderList)
+ err = a.orm.CreateAllowedSenders(ctx, allowedSenderList)
if err != nil {
a.lggr.Errorf("failed to update stored allowedSenderList: %w", err)
}
@@ -290,7 +290,7 @@ func (a *onchainAllowlist) getAllowedSendersBatched(ctx context.Context, tosCont
}
allowedSenderList = append(allowedSenderList, allowedSendersBatch...)
- err = a.orm.CreateAllowedSenders(allowedSendersBatch)
+ err = a.orm.CreateAllowedSenders(ctx, allowedSendersBatch)
if err != nil {
a.lggr.Errorf("failed to update stored allowedSenderList: %w", err)
}
@@ -330,7 +330,7 @@ func (a *onchainAllowlist) syncBlockedSenders(ctx context.Context, tosContract *
return errors.Wrap(err, "error calling GetAllowedSendersInRange")
}
- err = a.orm.DeleteAllowedSenders(blockedSendersBatch)
+ err = a.orm.DeleteAllowedSenders(ctx, blockedSendersBatch)
if err != nil {
a.lggr.Errorf("failed to delete blocked address from allowed list in storage: %w", err)
}
@@ -349,11 +349,11 @@ func (a *onchainAllowlist) update(addrList []common.Address) {
a.lggr.Infow("allowlist updated successfully", "len", len(addrList))
}
-func (a *onchainAllowlist) loadStoredAllowedSenderList() {
+func (a *onchainAllowlist) loadStoredAllowedSenderList(ctx context.Context) {
allowedList := make([]common.Address, 0)
offset := uint(0)
for {
- asBatch, err := a.orm.GetAllowedSenders(offset, a.config.StoredAllowlistBatchSize)
+ asBatch, err := a.orm.GetAllowedSenders(ctx, offset, a.config.StoredAllowlistBatchSize)
if err != nil {
a.lggr.Errorf("failed to get stored allowed senders: %w", err)
break
diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go
index 735c0bff7dc..d4900627bdb 100644
--- a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go
+++ b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go
@@ -58,8 +58,8 @@ func TestUpdateAndCheck(t *testing.T) {
}
orm := amocks.NewORM(t)
- orm.On("PurgeAllowedSenders").Times(1).Return(nil)
- orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
+ orm.On("PurgeAllowedSenders", mock.Anything).Times(1).Return(nil)
+ orm.On("CreateAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
@@ -99,8 +99,8 @@ func TestUpdateAndCheck(t *testing.T) {
}
orm := amocks.NewORM(t)
- orm.On("DeleteAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
- orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
+ orm.On("DeleteAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
+ orm.On("CreateAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
@@ -163,9 +163,9 @@ func TestUpdatePeriodically(t *testing.T) {
}
orm := amocks.NewORM(t)
- orm.On("PurgeAllowedSenders").Times(1).Return(nil)
- orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil)
- orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
+ orm.On("PurgeAllowedSenders", mock.Anything).Times(1).Return(nil)
+ orm.On("GetAllowedSenders", mock.Anything, uint(0), uint(1000)).Return([]common.Address{}, nil)
+ orm.On("CreateAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
@@ -207,9 +207,9 @@ func TestUpdatePeriodically(t *testing.T) {
}
orm := amocks.NewORM(t)
- orm.On("DeleteAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
- orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil)
- orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
+ orm.On("DeleteAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
+ orm.On("GetAllowedSenders", mock.Anything, uint(0), uint(1000)).Return([]common.Address{}, nil)
+ orm.On("CreateAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
@@ -258,8 +258,8 @@ func TestUpdateFromContract(t *testing.T) {
}
orm := amocks.NewORM(t)
- orm.On("PurgeAllowedSenders").Times(1).Return(nil)
- orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
+ orm.On("PurgeAllowedSenders", mock.Anything).Times(1).Return(nil)
+ orm.On("CreateAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil)
allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
@@ -301,8 +301,8 @@ func TestUpdateFromContract(t *testing.T) {
}
orm := amocks.NewORM(t)
- orm.On("DeleteAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil)
- orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil)
+ orm.On("DeleteAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil)
+ orm.On("CreateAllowedSenders", mock.Anything, []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil)
allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
diff --git a/core/services/gateway/handlers/functions/allowlist/mocks/orm.go b/core/services/gateway/handlers/functions/allowlist/mocks/orm.go
index daff33d8902..76121270518 100644
--- a/core/services/gateway/handlers/functions/allowlist/mocks/orm.go
+++ b/core/services/gateway/handlers/functions/allowlist/mocks/orm.go
@@ -3,10 +3,11 @@
package mocks
import (
+ context "context"
+
common "github.com/ethereum/go-ethereum/common"
- mock "github.com/stretchr/testify/mock"
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ mock "github.com/stretchr/testify/mock"
)
// ORM is an autogenerated mock type for the ORM type
@@ -14,24 +15,17 @@ type ORM struct {
mock.Mock
}
-// CreateAllowedSenders provides a mock function with given fields: allowedSenders, qopts
-func (_m *ORM) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, allowedSenders)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// CreateAllowedSenders provides a mock function with given fields: ctx, allowedSenders
+func (_m *ORM) CreateAllowedSenders(ctx context.Context, allowedSenders []common.Address) error {
+ ret := _m.Called(ctx, allowedSenders)
if len(ret) == 0 {
panic("no return value specified for CreateAllowedSenders")
}
var r0 error
- if rf, ok := ret.Get(0).(func([]common.Address, ...pg.QOpt) error); ok {
- r0 = rf(allowedSenders, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, []common.Address) error); ok {
+ r0 = rf(ctx, allowedSenders)
} else {
r0 = ret.Error(0)
}
@@ -39,24 +33,17 @@ func (_m *ORM) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg
return r0
}
-// DeleteAllowedSenders provides a mock function with given fields: blockedSenders, qopts
-func (_m *ORM) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, blockedSenders)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// DeleteAllowedSenders provides a mock function with given fields: ctx, blockedSenders
+func (_m *ORM) DeleteAllowedSenders(ctx context.Context, blockedSenders []common.Address) error {
+ ret := _m.Called(ctx, blockedSenders)
if len(ret) == 0 {
panic("no return value specified for DeleteAllowedSenders")
}
var r0 error
- if rf, ok := ret.Get(0).(func([]common.Address, ...pg.QOpt) error); ok {
- r0 = rf(blockedSenders, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, []common.Address) error); ok {
+ r0 = rf(ctx, blockedSenders)
} else {
r0 = ret.Error(0)
}
@@ -64,16 +51,9 @@ func (_m *ORM) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg
return r0
}
-// GetAllowedSenders provides a mock function with given fields: offset, limit, qopts
-func (_m *ORM) GetAllowedSenders(offset uint, limit uint, qopts ...pg.QOpt) ([]common.Address, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, offset, limit)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// GetAllowedSenders provides a mock function with given fields: ctx, offset, limit
+func (_m *ORM) GetAllowedSenders(ctx context.Context, offset uint, limit uint) ([]common.Address, error) {
+ ret := _m.Called(ctx, offset, limit)
if len(ret) == 0 {
panic("no return value specified for GetAllowedSenders")
@@ -81,19 +61,19 @@ func (_m *ORM) GetAllowedSenders(offset uint, limit uint, qopts ...pg.QOpt) ([]c
var r0 []common.Address
var r1 error
- if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) ([]common.Address, error)); ok {
- return rf(offset, limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint, uint) ([]common.Address, error)); ok {
+ return rf(ctx, offset, limit)
}
- if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) []common.Address); ok {
- r0 = rf(offset, limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint, uint) []common.Address); ok {
+ r0 = rf(ctx, offset, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]common.Address)
}
}
- if rf, ok := ret.Get(1).(func(uint, uint, ...pg.QOpt) error); ok {
- r1 = rf(offset, limit, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, uint, uint) error); ok {
+ r1 = rf(ctx, offset, limit)
} else {
r1 = ret.Error(1)
}
@@ -101,23 +81,17 @@ func (_m *ORM) GetAllowedSenders(offset uint, limit uint, qopts ...pg.QOpt) ([]c
return r0, r1
}
-// PurgeAllowedSenders provides a mock function with given fields: qopts
-func (_m *ORM) PurgeAllowedSenders(qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// PurgeAllowedSenders provides a mock function with given fields: ctx
+func (_m *ORM) PurgeAllowedSenders(ctx context.Context) error {
+ ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for PurgeAllowedSenders")
}
var r0 error
- if rf, ok := ret.Get(0).(func(...pg.QOpt) error); ok {
- r0 = rf(qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context) error); ok {
+ r0 = rf(ctx)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/gateway/handlers/functions/allowlist/orm.go b/core/services/gateway/handlers/functions/allowlist/orm.go
index ccacec81a43..7867c06d5d4 100644
--- a/core/services/gateway/handlers/functions/allowlist/orm.go
+++ b/core/services/gateway/handlers/functions/allowlist/orm.go
@@ -1,28 +1,27 @@
package allowlist
import (
+ "context"
"fmt"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
- "github.com/jmoiron/sqlx"
-
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
//go:generate mockery --quiet --name ORM --output ./mocks/ --case=underscore
type ORM interface {
- GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error)
- CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error
- DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.QOpt) error
- PurgeAllowedSenders(qopts ...pg.QOpt) error
+ GetAllowedSenders(ctx context.Context, offset, limit uint) ([]common.Address, error)
+ CreateAllowedSenders(ctx context.Context, allowedSenders []common.Address) error
+ DeleteAllowedSenders(ctx context.Context, blockedSenders []common.Address) error
+ PurgeAllowedSenders(ctx context.Context) error
}
type orm struct {
- q pg.Q
+ ds sqlutil.DataSource
lggr logger.Logger
routerContractAddress common.Address
}
@@ -36,19 +35,19 @@ const (
tableName = "functions_allowlist"
)
-func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, routerContractAddress common.Address) (ORM, error) {
- if db == nil || cfg == nil || lggr == nil || routerContractAddress == (common.Address{}) {
+func NewORM(ds sqlutil.DataSource, lggr logger.Logger, routerContractAddress common.Address) (ORM, error) {
+ if ds == nil || lggr == nil || routerContractAddress == (common.Address{}) {
return nil, ErrInvalidParameters
}
return &orm{
- q: pg.NewQ(db, lggr, cfg),
+ ds: ds,
lggr: lggr,
routerContractAddress: routerContractAddress,
}, nil
}
-func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) {
+func (o *orm) GetAllowedSenders(ctx context.Context, offset, limit uint) ([]common.Address, error) {
var addresses []common.Address
stmt := fmt.Sprintf(`
SELECT allowed_address
@@ -58,7 +57,7 @@ func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.
OFFSET $2
LIMIT $3;
`, tableName)
- err := o.q.WithOpts(qopts...).Select(&addresses, stmt, o.routerContractAddress, offset, limit)
+ err := o.ds.SelectContext(ctx, &addresses, stmt, o.routerContractAddress, offset, limit)
if err != nil {
return addresses, err
}
@@ -67,7 +66,7 @@ func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.
return addresses, nil
}
-func (o *orm) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error {
+func (o *orm) CreateAllowedSenders(ctx context.Context, allowedSenders []common.Address) error {
var valuesPlaceholder []string
for i := 1; i <= len(allowedSenders)*2; i += 2 {
valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("($%d, $%d)", i, i+1))
@@ -82,7 +81,7 @@ func (o *orm) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.
args = append(args, as, o.routerContractAddress)
}
- _, err := o.q.WithOpts(qopts...).Exec(stmt, args...)
+ _, err := o.ds.ExecContext(ctx, stmt, args...)
if err != nil {
return err
}
@@ -94,7 +93,7 @@ func (o *orm) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.
// DeleteAllowedSenders is used to remove blocked senders from the functions_allowlist table.
// This is achieved by specifying a list of blockedSenders to remove.
-func (o *orm) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.QOpt) error {
+func (o *orm) DeleteAllowedSenders(ctx context.Context, blockedSenders []common.Address) error {
var valuesPlaceholder []string
for i := 1; i <= len(blockedSenders); i++ {
valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("$%d", i+1))
@@ -110,7 +109,7 @@ func (o *orm) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.
args = append(args, bs)
}
- res, err := o.q.WithOpts(qopts...).Exec(stmt, args...)
+ res, err := o.ds.ExecContext(ctx, stmt, args...)
if err != nil {
return err
}
@@ -126,12 +125,12 @@ func (o *orm) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.
}
// PurgeAllowedSenders will remove all the allowed senders for the configured orm routerContractAddress
-func (o *orm) PurgeAllowedSenders(qopts ...pg.QOpt) error {
+func (o *orm) PurgeAllowedSenders(ctx context.Context) error {
stmt := fmt.Sprintf(`
DELETE FROM %s
WHERE router_contract_address = $1;`, tableName)
- res, err := o.q.WithOpts(qopts...).Exec(stmt, o.routerContractAddress)
+ res, err := o.ds.ExecContext(ctx, stmt, o.routerContractAddress)
if err != nil {
return err
}
diff --git a/core/services/gateway/handlers/functions/allowlist/orm_test.go b/core/services/gateway/handlers/functions/allowlist/orm_test.go
index 1d357616fab..2584e131968 100644
--- a/core/services/gateway/handlers/functions/allowlist/orm_test.go
+++ b/core/services/gateway/handlers/functions/allowlist/orm_test.go
@@ -20,17 +20,18 @@ func setupORM(t *testing.T) (allowlist.ORM, error) {
lggr = logger.TestLogger(t)
)
- return allowlist.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress())
+ return allowlist.NewORM(db, lggr, testutils.NewAddress())
}
func seedAllowedSenders(t *testing.T, orm allowlist.ORM, amount int) []common.Address {
+ ctx := testutils.Context(t)
storedAllowedSenders := make([]common.Address, amount)
for i := 0; i < amount; i++ {
address := testutils.NewAddress()
storedAllowedSenders[i] = address
}
- err := orm.CreateAllowedSenders(storedAllowedSenders)
+ err := orm.CreateAllowedSenders(ctx, storedAllowedSenders)
require.NoError(t, err)
return storedAllowedSenders
@@ -38,20 +39,22 @@ func seedAllowedSenders(t *testing.T, orm allowlist.ORM, amount int) []common.Ad
func TestORM_GetAllowedSenders(t *testing.T) {
t.Parallel()
t.Run("fetch first page", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
storedAllowedSenders := seedAllowedSenders(t, orm, 2)
- results, err := orm.GetAllowedSenders(0, 1)
+ results, err := orm.GetAllowedSenders(ctx, 0, 1)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, storedAllowedSenders[0], results[0])
})
t.Run("fetch second page", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
storedAllowedSenders := seedAllowedSenders(t, orm, 2)
- results, err := orm.GetAllowedSenders(1, 5)
+ results, err := orm.GetAllowedSenders(ctx, 1, 5)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, storedAllowedSenders[1], results[0])
@@ -62,42 +65,45 @@ func TestORM_CreateAllowedSenders(t *testing.T) {
t.Parallel()
t.Run("OK-create_an_allowed_sender", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
expected := testutils.NewAddress()
- err = orm.CreateAllowedSenders([]common.Address{expected})
+ err = orm.CreateAllowedSenders(ctx, []common.Address{expected})
require.NoError(t, err)
- results, err := orm.GetAllowedSenders(0, 1)
+ results, err := orm.GetAllowedSenders(ctx, 0, 1)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, expected, results[0])
})
t.Run("OK-create_an_existing_allowed_sender", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
expected := testutils.NewAddress()
- err = orm.CreateAllowedSenders([]common.Address{expected})
+ err = orm.CreateAllowedSenders(ctx, []common.Address{expected})
require.NoError(t, err)
- err = orm.CreateAllowedSenders([]common.Address{expected})
+ err = orm.CreateAllowedSenders(ctx, []common.Address{expected})
require.NoError(t, err)
- results, err := orm.GetAllowedSenders(0, 5)
+ results, err := orm.GetAllowedSenders(ctx, 0, 5)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, expected, results[0])
})
t.Run("OK-create_multiple_allowed_senders_in_one_query", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
expected := []common.Address{testutils.NewAddress(), testutils.NewAddress()}
- err = orm.CreateAllowedSenders(expected)
+ err = orm.CreateAllowedSenders(ctx, expected)
require.NoError(t, err)
- results, err := orm.GetAllowedSenders(0, 2)
+ results, err := orm.GetAllowedSenders(ctx, 0, 2)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, expected[0], results[0])
@@ -105,6 +111,7 @@ func TestORM_CreateAllowedSenders(t *testing.T) {
})
t.Run("OK-create_multiple_allowed_senders_with_duplicates", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
addr1 := testutils.NewAddress()
@@ -112,10 +119,10 @@ func TestORM_CreateAllowedSenders(t *testing.T) {
expected := []common.Address{addr1, addr2}
duplicatedAddressInput := []common.Address{addr1, addr1, addr1, addr2}
- err = orm.CreateAllowedSenders(duplicatedAddressInput)
+ err = orm.CreateAllowedSenders(ctx, duplicatedAddressInput)
require.NoError(t, err)
- results, err := orm.GetAllowedSenders(0, 10)
+ results, err := orm.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, expected[0], results[0])
@@ -127,46 +134,48 @@ func TestORM_DeleteAllowedSenders(t *testing.T) {
t.Parallel()
t.Run("OK-delete_blocked_sender_from_allowed_list", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
add1 := testutils.NewAddress()
add2 := testutils.NewAddress()
add3 := testutils.NewAddress()
- err = orm.CreateAllowedSenders([]common.Address{add1, add2, add3})
+ err = orm.CreateAllowedSenders(ctx, []common.Address{add1, add2, add3})
require.NoError(t, err)
- results, err := orm.GetAllowedSenders(0, 10)
+ results, err := orm.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 3, len(results), "incorrect results length")
require.Equal(t, add1, results[0])
- err = orm.DeleteAllowedSenders([]common.Address{add1, add3})
+ err = orm.DeleteAllowedSenders(ctx, []common.Address{add1, add3})
require.NoError(t, err)
- results, err = orm.GetAllowedSenders(0, 10)
+ results, err = orm.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, add2, results[0])
})
t.Run("OK-delete_non_existing_blocked_sender_from_allowed_list", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
add1 := testutils.NewAddress()
add2 := testutils.NewAddress()
- err = orm.CreateAllowedSenders([]common.Address{add1, add2})
+ err = orm.CreateAllowedSenders(ctx, []common.Address{add1, add2})
require.NoError(t, err)
- results, err := orm.GetAllowedSenders(0, 10)
+ results, err := orm.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, add1, results[0])
add3 := testutils.NewAddress()
- err = orm.DeleteAllowedSenders([]common.Address{add3})
+ err = orm.DeleteAllowedSenders(ctx, []common.Address{add3})
require.NoError(t, err)
- results, err = orm.GetAllowedSenders(0, 10)
+ results, err = orm.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, add1, results[0])
@@ -178,36 +187,38 @@ func TestORM_PurgeAllowedSenders(t *testing.T) {
t.Parallel()
t.Run("OK-purge_allowed_list", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
add1 := testutils.NewAddress()
add2 := testutils.NewAddress()
add3 := testutils.NewAddress()
- err = orm.CreateAllowedSenders([]common.Address{add1, add2, add3})
+ err = orm.CreateAllowedSenders(ctx, []common.Address{add1, add2, add3})
require.NoError(t, err)
- results, err := orm.GetAllowedSenders(0, 10)
+ results, err := orm.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 3, len(results), "incorrect results length")
require.Equal(t, add1, results[0])
- err = orm.PurgeAllowedSenders()
+ err = orm.PurgeAllowedSenders(ctx)
require.NoError(t, err)
- results, err = orm.GetAllowedSenders(0, 10)
+ results, err = orm.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 0, len(results), "incorrect results length")
})
t.Run("OK-purge_allowed_list_for_contract_address", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm1, err := setupORM(t)
require.NoError(t, err)
add1 := testutils.NewAddress()
add2 := testutils.NewAddress()
- err = orm1.CreateAllowedSenders([]common.Address{add1, add2})
+ err = orm1.CreateAllowedSenders(ctx, []common.Address{add1, add2})
require.NoError(t, err)
- results, err := orm1.GetAllowedSenders(0, 10)
+ results, err := orm1.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, add1, results[0])
@@ -216,22 +227,22 @@ func TestORM_PurgeAllowedSenders(t *testing.T) {
require.NoError(t, err)
add3 := testutils.NewAddress()
add4 := testutils.NewAddress()
- err = orm2.CreateAllowedSenders([]common.Address{add3, add4})
+ err = orm2.CreateAllowedSenders(ctx, []common.Address{add3, add4})
require.NoError(t, err)
- results, err = orm2.GetAllowedSenders(0, 10)
+ results, err = orm2.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, add3, results[0])
- err = orm2.PurgeAllowedSenders()
+ err = orm2.PurgeAllowedSenders(ctx)
require.NoError(t, err)
- results, err = orm2.GetAllowedSenders(0, 10)
+ results, err = orm2.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 0, len(results), "incorrect results length")
- results, err = orm1.GetAllowedSenders(0, 10)
+ results, err = orm1.GetAllowedSenders(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, add1, results[0])
@@ -241,15 +252,15 @@ func TestORM_PurgeAllowedSenders(t *testing.T) {
func Test_NewORM(t *testing.T) {
t.Run("OK-create_ORM", func(t *testing.T) {
- _, err := allowlist.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), testutils.NewAddress())
+ _, err := allowlist.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), testutils.NewAddress())
require.NoError(t, err)
})
t.Run("NOK-create_ORM_with_nil_fields", func(t *testing.T) {
- _, err := allowlist.NewORM(nil, nil, nil, common.Address{})
+ _, err := allowlist.NewORM(nil, nil, common.Address{})
require.Error(t, err)
})
t.Run("NOK-create_ORM_with_empty_address", func(t *testing.T) {
- _, err := allowlist.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), common.Address{})
+ _, err := allowlist.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), common.Address{})
require.Error(t, err)
})
}
diff --git a/core/services/gateway/handlers/functions/handler.functions.go b/core/services/gateway/handlers/functions/handler.functions.go
index ff272e4e577..692534db598 100644
--- a/core/services/gateway/handlers/functions/handler.functions.go
+++ b/core/services/gateway/handlers/functions/handler.functions.go
@@ -114,7 +114,7 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con
return nil, err2
}
- orm, err2 := fallow.NewORM(db, lggr, qcfg, cfg.OnchainAllowlist.ContractAddress)
+ orm, err2 := fallow.NewORM(db, lggr, cfg.OnchainAllowlist.ContractAddress)
if err2 != nil {
return nil, err2
}
@@ -143,7 +143,7 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con
return nil, err2
}
- orm, err2 := fsub.NewORM(db, lggr, qcfg, cfg.OnchainSubscriptions.ContractAddress)
+ orm, err2 := fsub.NewORM(db, lggr, cfg.OnchainSubscriptions.ContractAddress)
if err2 != nil {
return nil, err2
}
diff --git a/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go b/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go
index 0f278aa49b0..16a82a488b4 100644
--- a/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go
+++ b/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go
@@ -3,8 +3,9 @@
package mocks
import (
+ context "context"
+
subscriptions "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions"
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
mock "github.com/stretchr/testify/mock"
)
@@ -13,16 +14,9 @@ type ORM struct {
mock.Mock
}
-// GetSubscriptions provides a mock function with given fields: offset, limit, qopts
-func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]subscriptions.StoredSubscription, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, offset, limit)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// GetSubscriptions provides a mock function with given fields: ctx, offset, limit
+func (_m *ORM) GetSubscriptions(ctx context.Context, offset uint, limit uint) ([]subscriptions.StoredSubscription, error) {
+ ret := _m.Called(ctx, offset, limit)
if len(ret) == 0 {
panic("no return value specified for GetSubscriptions")
@@ -30,19 +24,19 @@ func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]su
var r0 []subscriptions.StoredSubscription
var r1 error
- if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) ([]subscriptions.StoredSubscription, error)); ok {
- return rf(offset, limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint, uint) ([]subscriptions.StoredSubscription, error)); ok {
+ return rf(ctx, offset, limit)
}
- if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) []subscriptions.StoredSubscription); ok {
- r0 = rf(offset, limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint, uint) []subscriptions.StoredSubscription); ok {
+ r0 = rf(ctx, offset, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]subscriptions.StoredSubscription)
}
}
- if rf, ok := ret.Get(1).(func(uint, uint, ...pg.QOpt) error); ok {
- r1 = rf(offset, limit, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, uint, uint) error); ok {
+ r1 = rf(ctx, offset, limit)
} else {
r1 = ret.Error(1)
}
@@ -50,24 +44,17 @@ func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]su
return r0, r1
}
-// UpsertSubscription provides a mock function with given fields: subscription, qopts
-func (_m *ORM) UpsertSubscription(subscription subscriptions.StoredSubscription, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, subscription)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// UpsertSubscription provides a mock function with given fields: ctx, subscription
+func (_m *ORM) UpsertSubscription(ctx context.Context, subscription subscriptions.StoredSubscription) error {
+ ret := _m.Called(ctx, subscription)
if len(ret) == 0 {
panic("no return value specified for UpsertSubscription")
}
var r0 error
- if rf, ok := ret.Get(0).(func(subscriptions.StoredSubscription, ...pg.QOpt) error); ok {
- r0 = rf(subscription, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, subscriptions.StoredSubscription) error); ok {
+ r0 = rf(ctx, subscription)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/gateway/handlers/functions/subscriptions/orm.go b/core/services/gateway/handlers/functions/subscriptions/orm.go
index 369291ace54..d97437a39dc 100644
--- a/core/services/gateway/handlers/functions/subscriptions/orm.go
+++ b/core/services/gateway/handlers/functions/subscriptions/orm.go
@@ -1,6 +1,7 @@
package subscriptions
import (
+ "context"
"fmt"
"math/big"
@@ -8,21 +9,19 @@ import (
"github.com/lib/pq"
"github.com/pkg/errors"
- "github.com/jmoiron/sqlx"
-
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
//go:generate mockery --quiet --name ORM --output ./mocks/ --case=underscore
type ORM interface {
- GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]StoredSubscription, error)
- UpsertSubscription(subscription StoredSubscription, qopts ...pg.QOpt) error
+ GetSubscriptions(ctx context.Context, offset, limit uint) ([]StoredSubscription, error)
+ UpsertSubscription(ctx context.Context, subscription StoredSubscription) error
}
type orm struct {
- q pg.Q
+ ds sqlutil.DataSource
lggr logger.Logger
routerContractAddress common.Address
}
@@ -47,19 +46,19 @@ type storedSubscriptionRow struct {
RouterContractAddress common.Address
}
-func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, routerContractAddress common.Address) (ORM, error) {
- if db == nil || cfg == nil || lggr == nil || routerContractAddress == (common.Address{}) {
+func NewORM(ds sqlutil.DataSource, lggr logger.Logger, routerContractAddress common.Address) (ORM, error) {
+ if ds == nil || lggr == nil || routerContractAddress == (common.Address{}) {
return nil, ErrInvalidParameters
}
return &orm{
- q: pg.NewQ(db, lggr, cfg),
+ ds: ds,
lggr: lggr,
routerContractAddress: routerContractAddress,
}, nil
}
-func (o *orm) GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]StoredSubscription, error) {
+func (o *orm) GetSubscriptions(ctx context.Context, offset, limit uint) ([]StoredSubscription, error) {
var storedSubscriptions []StoredSubscription
var storedSubscriptionRows []storedSubscriptionRow
stmt := fmt.Sprintf(`
@@ -70,7 +69,7 @@ func (o *orm) GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]StoredSu
OFFSET $2
LIMIT $3;
`, tableName)
- err := o.q.WithOpts(qopts...).Select(&storedSubscriptionRows, stmt, o.routerContractAddress, offset, limit)
+ err := o.ds.SelectContext(ctx, &storedSubscriptionRows, stmt, o.routerContractAddress, offset, limit)
if err != nil {
return storedSubscriptions, err
}
@@ -84,7 +83,7 @@ func (o *orm) GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]StoredSu
// UpsertSubscription will update if a subscription exists or create if it does not.
// In case a subscription gets deleted we will update it with an owner address equal to 0x0.
-func (o *orm) UpsertSubscription(subscription StoredSubscription, qopts ...pg.QOpt) error {
+func (o *orm) UpsertSubscription(ctx context.Context, subscription StoredSubscription) error {
stmt := fmt.Sprintf(`
INSERT INTO %s (subscription_id, owner, balance, blocked_balance, proposed_owner, consumers, flags, router_contract_address)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT (subscription_id, router_contract_address) DO UPDATE
@@ -103,7 +102,8 @@ func (o *orm) UpsertSubscription(subscription StoredSubscription, qopts ...pg.QO
consumers = append(consumers, c.Bytes())
}
- _, err := o.q.WithOpts(qopts...).Exec(
+ _, err := o.ds.ExecContext(
+ ctx,
stmt,
subscription.SubscriptionID,
subscription.Owner,
diff --git a/core/services/gateway/handlers/functions/subscriptions/orm_test.go b/core/services/gateway/handlers/functions/subscriptions/orm_test.go
index 6cb1146f03c..e2d7cfe9f49 100644
--- a/core/services/gateway/handlers/functions/subscriptions/orm_test.go
+++ b/core/services/gateway/handlers/functions/subscriptions/orm_test.go
@@ -27,10 +27,11 @@ func setupORM(t *testing.T) (subscriptions.ORM, error) {
lggr = logger.TestLogger(t)
)
- return subscriptions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress())
+ return subscriptions.NewORM(db, lggr, testutils.NewAddress())
}
func seedSubscriptions(t *testing.T, orm subscriptions.ORM, amount int) []subscriptions.StoredSubscription {
+ ctx := testutils.Context(t)
storedSubscriptions := make([]subscriptions.StoredSubscription, 0)
for i := amount; i > 0; i-- {
cs := subscriptions.StoredSubscription{
@@ -45,7 +46,7 @@ func seedSubscriptions(t *testing.T, orm subscriptions.ORM, amount int) []subscr
},
}
storedSubscriptions = append(storedSubscriptions, cs)
- err := orm.UpsertSubscription(cs)
+ err := orm.UpsertSubscription(ctx, cs)
require.NoError(t, err)
}
return storedSubscriptions
@@ -54,20 +55,22 @@ func seedSubscriptions(t *testing.T, orm subscriptions.ORM, amount int) []subscr
func TestORM_GetSubscriptions(t *testing.T) {
t.Parallel()
t.Run("fetch first page", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
storedSubscriptions := seedSubscriptions(t, orm, 2)
- results, err := orm.GetSubscriptions(0, 1)
+ results, err := orm.GetSubscriptions(ctx, 0, 1)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, storedSubscriptions[1], results[0])
})
t.Run("fetch second page", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
storedSubscriptions := seedSubscriptions(t, orm, 2)
- results, err := orm.GetSubscriptions(1, 5)
+ results, err := orm.GetSubscriptions(ctx, 1, 5)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, storedSubscriptions[0], results[0])
@@ -78,6 +81,7 @@ func TestORM_UpsertSubscription(t *testing.T) {
t.Parallel()
t.Run("create a subscription", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
expected := subscriptions.StoredSubscription{
@@ -91,16 +95,17 @@ func TestORM_UpsertSubscription(t *testing.T) {
Flags: defaultFlags,
},
}
- err = orm.UpsertSubscription(expected)
+ err = orm.UpsertSubscription(ctx, expected)
require.NoError(t, err)
- results, err := orm.GetSubscriptions(0, 1)
+ results, err := orm.GetSubscriptions(ctx, 0, 1)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, expected, results[0])
})
t.Run("update a subscription", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
@@ -115,7 +120,7 @@ func TestORM_UpsertSubscription(t *testing.T) {
Flags: defaultFlags,
},
}
- err = orm.UpsertSubscription(expectedUpdated)
+ err = orm.UpsertSubscription(ctx, expectedUpdated)
require.NoError(t, err)
expectedNotUpdated := subscriptions.StoredSubscription{
@@ -129,15 +134,15 @@ func TestORM_UpsertSubscription(t *testing.T) {
Flags: defaultFlags,
},
}
- err = orm.UpsertSubscription(expectedNotUpdated)
+ err = orm.UpsertSubscription(ctx, expectedNotUpdated)
require.NoError(t, err)
// update the balance value
expectedUpdated.Balance = big.NewInt(20)
- err = orm.UpsertSubscription(expectedUpdated)
+ err = orm.UpsertSubscription(ctx, expectedUpdated)
require.NoError(t, err)
- results, err := orm.GetSubscriptions(0, 5)
+ results, err := orm.GetSubscriptions(ctx, 0, 5)
require.NoError(t, err)
require.Equal(t, 2, len(results), "incorrect results length")
require.Equal(t, expectedNotUpdated, results[1])
@@ -145,6 +150,7 @@ func TestORM_UpsertSubscription(t *testing.T) {
})
t.Run("update a deleted subscription", func(t *testing.T) {
+ ctx := testutils.Context(t)
orm, err := setupORM(t)
require.NoError(t, err)
@@ -159,7 +165,7 @@ func TestORM_UpsertSubscription(t *testing.T) {
Flags: defaultFlags,
},
}
- err = orm.UpsertSubscription(subscription)
+ err = orm.UpsertSubscription(ctx, subscription)
require.NoError(t, err)
// empty subscription
@@ -172,24 +178,25 @@ func TestORM_UpsertSubscription(t *testing.T) {
Flags: [32]byte{},
}
- err = orm.UpsertSubscription(subscription)
+ err = orm.UpsertSubscription(ctx, subscription)
require.NoError(t, err)
- results, err := orm.GetSubscriptions(0, 5)
+ results, err := orm.GetSubscriptions(ctx, 0, 5)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
require.Equal(t, subscription, results[0])
})
t.Run("create a subscription with same id but different router address", func(t *testing.T) {
+ ctx := testutils.Context(t)
var (
db = pgtest.NewSqlxDB(t)
lggr = logger.TestLogger(t)
)
- orm1, err := subscriptions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress())
+ orm1, err := subscriptions.NewORM(db, lggr, testutils.NewAddress())
require.NoError(t, err)
- orm2, err := subscriptions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress())
+ orm2, err := subscriptions.NewORM(db, lggr, testutils.NewAddress())
require.NoError(t, err)
subscription := subscriptions.StoredSubscription{
@@ -204,42 +211,43 @@ func TestORM_UpsertSubscription(t *testing.T) {
},
}
- err = orm1.UpsertSubscription(subscription)
+ err = orm1.UpsertSubscription(ctx, subscription)
require.NoError(t, err)
// should update the existing subscription
subscription.Balance = assets.Ether(12).ToInt()
- err = orm1.UpsertSubscription(subscription)
+ err = orm1.UpsertSubscription(ctx, subscription)
require.NoError(t, err)
- results, err := orm1.GetSubscriptions(0, 10)
+ results, err := orm1.GetSubscriptions(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
// should create a new subscription because it comes from a different router contract
- err = orm2.UpsertSubscription(subscription)
+ err = orm2.UpsertSubscription(ctx, subscription)
require.NoError(t, err)
- results, err = orm1.GetSubscriptions(0, 10)
+ results, err = orm1.GetSubscriptions(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
- results, err = orm2.GetSubscriptions(0, 10)
+ results, err = orm2.GetSubscriptions(ctx, 0, 10)
require.NoError(t, err)
require.Equal(t, 1, len(results), "incorrect results length")
})
}
func Test_NewORM(t *testing.T) {
+ t.Parallel()
t.Run("OK-create_ORM", func(t *testing.T) {
- _, err := subscriptions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), testutils.NewAddress())
+ _, err := subscriptions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), testutils.NewAddress())
require.NoError(t, err)
})
t.Run("NOK-create_ORM_with_nil_fields", func(t *testing.T) {
- _, err := subscriptions.NewORM(nil, nil, nil, common.Address{})
+ _, err := subscriptions.NewORM(nil, nil, common.Address{})
require.Error(t, err)
})
t.Run("NOK-create_ORM_with_empty_address", func(t *testing.T) {
- _, err := subscriptions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), common.Address{})
+ _, err := subscriptions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), common.Address{})
require.Error(t, err)
})
}
diff --git a/core/services/gateway/handlers/functions/subscriptions/subscriptions.go b/core/services/gateway/handlers/functions/subscriptions/subscriptions.go
index e90201a31a9..d481ecf12ed 100644
--- a/core/services/gateway/handlers/functions/subscriptions/subscriptions.go
+++ b/core/services/gateway/handlers/functions/subscriptions/subscriptions.go
@@ -99,7 +99,7 @@ func (s *onchainSubscriptions) Start(ctx context.Context) error {
return errors.New("OnchainSubscriptionsConfig.UpdateRangeSize must be greater than 0")
}
- s.loadStoredSubscriptions()
+ s.loadStoredSubscriptions(ctx)
s.closeWait.Add(1)
go s.queryLoop()
@@ -206,7 +206,7 @@ func (s *onchainSubscriptions) querySubscriptionsRange(ctx context.Context, bloc
subscription := subscription
updated := s.subscriptions.UpdateSubscription(subscriptionId, &subscription)
if updated {
- if err = s.orm.UpsertSubscription(StoredSubscription{
+ if err = s.orm.UpsertSubscription(ctx, StoredSubscription{
SubscriptionID: subscriptionId,
IFunctionsSubscriptionsSubscription: subscription,
}); err != nil {
@@ -226,10 +226,10 @@ func (s *onchainSubscriptions) getSubscriptionsCount(ctx context.Context, blockN
})
}
-func (s *onchainSubscriptions) loadStoredSubscriptions() {
+func (s *onchainSubscriptions) loadStoredSubscriptions(ctx context.Context) {
offset := uint(0)
for {
- csBatch, err := s.orm.GetSubscriptions(offset, s.config.StoreBatchSize)
+ csBatch, err := s.orm.GetSubscriptions(ctx, offset, s.config.StoreBatchSize)
if err != nil {
break
}
diff --git a/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go b/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go
index be1d2520434..04a5d14102f 100644
--- a/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go
+++ b/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go
@@ -29,6 +29,7 @@ const (
)
func TestSubscriptions_OnePass(t *testing.T) {
+ t.Parallel()
getSubscriptionCount := hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000003")
getSubscriptionsInRange := hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000109e6e1b12098cc8f3a1e9719a817ec53ab9b35c000000000000000000000000000000000000000000000000000034e23f515cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f5340f0968ee8b7dfd97e3327a6139273cc2c4fa000000000000000000000000000000000000000000000001158e460913d000000000000000000000000000009ed925d8206a4f88a2f643b28b3035b315753cd60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bc14b92364c75e20000000000000000000000009ed925d8206a4f88a2f643b28b3035b315753cd60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005439e5881a529f3ccbffc0e82d49f9db3950aefe")
@@ -51,8 +52,8 @@ func TestSubscriptions_OnePass(t *testing.T) {
UpdateRangeSize: 3,
}
orm := smocks.NewORM(t)
- orm.On("GetSubscriptions", uint(0), uint(100)).Return([]subscriptions.StoredSubscription{}, nil)
- orm.On("UpsertSubscription", mock.Anything).Return(nil)
+ orm.On("GetSubscriptions", mock.Anything, uint(0), uint(100)).Return([]subscriptions.StoredSubscription{}, nil)
+ orm.On("UpsertSubscription", mock.Anything, mock.Anything).Return(nil)
subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
@@ -72,6 +73,7 @@ func TestSubscriptions_OnePass(t *testing.T) {
}
func TestSubscriptions_MultiPass(t *testing.T) {
+ t.Parallel()
const ncycles int32 = 5
var currentCycle atomic.Int32
getSubscriptionCount := hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000006")
@@ -102,8 +104,8 @@ func TestSubscriptions_MultiPass(t *testing.T) {
UpdateRangeSize: 3,
}
orm := smocks.NewORM(t)
- orm.On("GetSubscriptions", uint(0), uint(100)).Return([]subscriptions.StoredSubscription{}, nil)
- orm.On("UpsertSubscription", mock.Anything).Return(nil)
+ orm.On("GetSubscriptions", mock.Anything, uint(0), uint(100)).Return([]subscriptions.StoredSubscription{}, nil)
+ orm.On("UpsertSubscription", mock.Anything, mock.Anything).Return(nil)
subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
@@ -119,6 +121,7 @@ func TestSubscriptions_MultiPass(t *testing.T) {
}
func TestSubscriptions_Stored(t *testing.T) {
+ t.Parallel()
getSubscriptionCount := hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000003")
getSubscriptionsInRange := hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000109e6e1b12098cc8f3a1e9719a817ec53ab9b35c000000000000000000000000000000000000000000000000000034e23f515cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f5340f0968ee8b7dfd97e3327a6139273cc2c4fa000000000000000000000000000000000000000000000001158e460913d000000000000000000000000000009ed925d8206a4f88a2f643b28b3035b315753cd60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bc14b92364c75e20000000000000000000000009ed925d8206a4f88a2f643b28b3035b315753cd60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005439e5881a529f3ccbffc0e82d49f9db3950aefe")
@@ -144,7 +147,7 @@ func TestSubscriptions_Stored(t *testing.T) {
expectedBalance := big.NewInt(5)
orm := smocks.NewORM(t)
- orm.On("GetSubscriptions", uint(0), uint(1)).Return([]subscriptions.StoredSubscription{
+ orm.On("GetSubscriptions", mock.Anything, uint(0), uint(1)).Return([]subscriptions.StoredSubscription{
{
SubscriptionID: 1,
IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{
@@ -154,8 +157,8 @@ func TestSubscriptions_Stored(t *testing.T) {
},
},
}, nil)
- orm.On("GetSubscriptions", uint(1), uint(1)).Return([]subscriptions.StoredSubscription{}, nil)
- orm.On("UpsertSubscription", mock.Anything).Return(nil)
+ orm.On("GetSubscriptions", mock.Anything, uint(1), uint(1)).Return([]subscriptions.StoredSubscription{}, nil)
+ orm.On("UpsertSubscription", mock.Anything, mock.Anything).Return(nil)
subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t))
require.NoError(t, err)
diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go
index 1e714da5908..c60f096c358 100644
--- a/core/services/job/job_orm_test.go
+++ b/core/services/job/job_orm_test.go
@@ -82,14 +82,14 @@ func TestORM(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
- borm := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ borm := bridges.NewORM(db)
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
_, address := cltest.MustInsertRandomKey(t, ethKeyStore)
jb := makeOCRJobSpec(t, address, bridge.Name.String(), bridge2.Name.String())
@@ -346,15 +346,14 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) {
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
- scopedConfig := evmtest.NewChainScopedConfig(t, config)
- korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
+ korm := keeper.NewORM(db, logger.TestLogger(t))
t.Run("it deletes records for offchainreporting jobs", func(t *testing.T) {
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
@@ -381,8 +380,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) {
t.Run("it deletes records for keeper jobs", func(t *testing.T) {
registry, keeperJob := cltest.MustInsertKeeperRegistry(t, db, korm, keyStore.Eth(), 0, 1, 20)
- scoped := evmtest.NewChainScopedConfig(t, config)
- cltest.MustInsertUpkeepForRegistry(t, db, scoped.Database(), registry)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry)
cltest.AssertCount(t, db, "keeper_specs", 1)
cltest.AssertCount(t, db, "keeper_registries", 1)
@@ -414,7 +412,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) {
})
t.Run("it deletes records for webhook jobs", func(t *testing.T) {
- ei := cltest.MustInsertExternalInitiator(t, bridges.NewORM(db, logger.TestLogger(t), config.Database()))
+ ei := cltest.MustInsertExternalInitiator(t, bridges.NewORM(db))
jb, webhookSpec := cltest.MustInsertWebhookSpec(t, db)
_, err := db.Exec(`INSERT INTO external_initiator_webhook_specs (external_initiator_id, webhook_spec_id, spec) VALUES ($1,$2,$3)`, ei.ID, webhookSpec.ID, `{"ei": "foo", "name": "webhookSpecTwoEIs"}`)
require.NoError(t, err)
@@ -429,7 +427,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) {
t.Run("does not allow to delete external initiators if they have referencing external_initiator_webhook_specs", func(t *testing.T) {
// create new db because this will rollback transaction and poison it
db := pgtest.NewSqlxDB(t)
- ei := cltest.MustInsertExternalInitiator(t, bridges.NewORM(db, logger.TestLogger(t), config.Database()))
+ ei := cltest.MustInsertExternalInitiator(t, bridges.NewORM(db))
_, webhookSpec := cltest.MustInsertWebhookSpec(t, db)
_, err := db.Exec(`INSERT INTO external_initiator_webhook_specs (external_initiator_id, webhook_spec_id, spec) VALUES ($1,$2,$3)`, ei.ID, webhookSpec.ID, `{"ei": "foo", "name": "webhookSpecTwoEIs"}`)
require.NoError(t, err)
@@ -446,8 +444,8 @@ func TestORM_CreateJob_VRFV2(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
@@ -530,8 +528,8 @@ func TestORM_CreateJob_VRFV2Plus(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
fromAddresses := []string{cltest.NewEIP55Address().String(), cltest.NewEIP55Address().String()}
@@ -617,8 +615,8 @@ func TestORM_CreateJob_OCRBootstrap(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := ocrbootstrap.ValidatedBootstrapSpecToml(testspecs.GetOCRBootstrapSpec())
@@ -643,8 +641,8 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) {
keyStore := cltest.NewKeyStore(t, db, config.Database())
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
@@ -738,16 +736,16 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
// defaultChainID is deprecated
defaultChainID := customChainID
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
// Custom Chain Job
externalJobID := uuid.NullUUID{UUID: uuid.New(), Valid: true}
@@ -807,8 +805,8 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) {
require.NoError(t, keyStore.OCR2().Add(cltest.DefaultOCR2Key))
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
@@ -868,8 +866,8 @@ func TestORM_CreateJob_OCR2_Sending_Keys_Transmitter_Keys_Validations(t *testing
require.NoError(t, keyStore.OCR2().Add(cltest.DefaultOCR2Key))
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
@@ -988,13 +986,13 @@ func Test_FindJobs(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
@@ -1069,13 +1067,13 @@ func Test_FindJob(t *testing.T) {
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
require.NoError(t, keyStore.CSA().Add(cltest.DefaultCSAKey))
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
// Create two jobs. Each job has the same Transmitter Address but on a different chain.
// Must uniquely name the OCR Specs to properly insert a new job in the job table.
@@ -1252,8 +1250,8 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) {
keyStore := cltest.NewKeyStore(t, db, config.Database())
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec())
@@ -1300,14 +1298,14 @@ func Test_FindPipelineRuns(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
externalJobID := uuid.New()
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
@@ -1361,14 +1359,14 @@ func Test_PipelineRunsByJobID(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
externalJobID := uuid.New()
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
@@ -1421,9 +1419,8 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
- lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, lggr, config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
@@ -1432,8 +1429,8 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) {
jobs := make([]job.Job, 11)
for j := 0; j < len(jobs); j++ {
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
jobID := uuid.New().String()
key, err := ethkey.NewV2()
@@ -1530,14 +1527,14 @@ func Test_FindPipelineRunsByIDs(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
externalJobID := uuid.New()
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
@@ -1588,8 +1585,8 @@ func Test_FindPipelineRunByID(t *testing.T) {
err := keyStore.OCR().Add(cltest.DefaultOCRKey)
require.NoError(t, err)
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec())
@@ -1631,8 +1628,8 @@ func Test_FindJobWithoutSpecErrors(t *testing.T) {
err := keyStore.OCR().Add(cltest.DefaultOCRKey)
require.NoError(t, err)
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec())
@@ -1668,8 +1665,8 @@ func Test_FindSpecErrorsByJobIDs(t *testing.T) {
err := keyStore.OCR().Add(cltest.DefaultOCRKey)
require.NoError(t, err)
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec())
@@ -1702,14 +1699,14 @@ func Test_CountPipelineRunsByJobID(t *testing.T) {
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
externalJobID := uuid.New()
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
@@ -1743,6 +1740,7 @@ func Test_CountPipelineRunsByJobID(t *testing.T) {
func mustInsertPipelineRun(t *testing.T, orm pipeline.ORM, j job.Job) pipeline.Run {
t.Helper()
+ ctx := testutils.Context(t)
run := pipeline.Run{
PipelineSpecID: j.PipelineSpecID,
@@ -1753,7 +1751,7 @@ func mustInsertPipelineRun(t *testing.T, orm pipeline.ORM, j job.Job) pipeline.R
CreatedAt: time.Now(),
FinishedAt: null.Time{},
}
- err := orm.CreateRun(&run)
+ err := orm.CreateRun(ctx, &run)
require.NoError(t, err)
return run
}
diff --git a/core/services/job/job_pipeline_orm_integration_test.go b/core/services/job/job_pipeline_orm_integration_test.go
index c7842e1b160..696005c270e 100644
--- a/core/services/job/job_pipeline_orm_integration_test.go
+++ b/core/services/job/job_pipeline_orm_integration_test.go
@@ -122,18 +122,19 @@ func TestPipelineORM_Integration(t *testing.T) {
ds1.BaseTask = pipeline.NewBaseTask(0, "ds1", nil, []pipeline.Task{ds1_parse}, 0)
ds2.BaseTask = pipeline.NewBaseTask(3, "ds2", nil, []pipeline.Task{ds2_parse}, 0)
expectedTasks := []pipeline.Task{ds1, ds1_parse, ds1_multiply, ds2, ds2_parse, ds2_multiply, answer1, answer2}
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
t.Run("creates task DAGs", func(t *testing.T) {
+ ctx := testutils.Context(t)
clearJobsDb(t, db)
- orm := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
+ orm := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
p, err := pipeline.Parse(DotStr)
require.NoError(t, err)
- specID, err = orm.CreateSpec(*p, models.Interval(0))
+ specID, err = orm.CreateSpec(ctx, nil, *p, models.Interval(0))
require.NoError(t, err)
var pipelineSpecs []pipeline.Spec
@@ -152,8 +153,8 @@ func TestPipelineORM_Integration(t *testing.T) {
lggr := logger.TestLogger(t)
cfg := configtest.NewTestGeneralConfig(t)
clearJobsDb(t, db)
- orm := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- btORM := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
+ orm := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ btORM := bridges.NewORM(db)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{Client: evmtest.NewEthClientMockWithDefaultChain(t), DB: db, GeneralConfig: config, KeyStore: ethKeyStore})
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
runner := pipeline.NewRunner(orm, btORM, config.JobPipeline(), cfg.WebServer(), legacyChains, nil, nil, lggr, nil, nil)
diff --git a/core/services/job/kv_orm_test.go b/core/services/job/kv_orm_test.go
index 94a6ec15f1f..3ba03b8bc3c 100644
--- a/core/services/job/kv_orm_test.go
+++ b/core/services/job/kv_orm_test.go
@@ -29,8 +29,8 @@ func TestJobKVStore(t *testing.T) {
lggr := logger.TestLogger(t)
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobID := int32(1337)
kvStore := job.NewKVStore(jobID, db, config.Database(), lggr)
diff --git a/core/services/job/mocks/orm.go b/core/services/job/mocks/orm.go
index 1068f511cdc..44b8c1f5be8 100644
--- a/core/services/job/mocks/orm.go
+++ b/core/services/job/mocks/orm.go
@@ -26,17 +26,17 @@ type ORM struct {
mock.Mock
}
-// AssertBridgesExist provides a mock function with given fields: p
-func (_m *ORM) AssertBridgesExist(p pipeline.Pipeline) error {
- ret := _m.Called(p)
+// AssertBridgesExist provides a mock function with given fields: ctx, p
+func (_m *ORM) AssertBridgesExist(ctx context.Context, p pipeline.Pipeline) error {
+ ret := _m.Called(ctx, p)
if len(ret) == 0 {
panic("no return value specified for AssertBridgesExist")
}
var r0 error
- if rf, ok := ret.Get(0).(func(pipeline.Pipeline) error); ok {
- r0 = rf(p)
+ if rf, ok := ret.Get(0).(func(context.Context, pipeline.Pipeline) error); ok {
+ r0 = rf(ctx, p)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/job/models.go b/core/services/job/models.go
index 4d75c7d90d2..67b7b8b0bbe 100644
--- a/core/services/job/models.go
+++ b/core/services/job/models.go
@@ -165,6 +165,8 @@ type Job struct {
LiquidityBalancerSpecID *int32
PipelineSpecID int32 // This is deprecated in favor of the `job_pipeline_specs` table relationship
PipelineSpec *pipeline.Spec
+ WorkflowSpecID *int32
+ WorkflowSpec *WorkflowSpec
JobSpecErrors []SpecError
Type Type `toml:"type"`
SchemaVersion uint32 `toml:"schemaVersion"`
@@ -821,3 +823,29 @@ type LiquidityBalancerSpec struct {
LiquidityBalancerConfig string `toml:"liquidityBalancerConfig" db:"liquidity_balancer_config"`
}
+
+type WorkflowSpec struct {
+ ID int32 `toml:"-"`
+ WorkflowID string `toml:"workflowId"`
+ Workflow string `toml:"workflow"`
+ WorkflowOwner string `toml:"workflowOwner"`
+ CreatedAt time.Time `toml:"-"`
+ UpdatedAt time.Time `toml:"-"`
+}
+
+const (
+ workflowIDLen = 64
+ workflowOwnerLen = 40
+)
+
+func (w *WorkflowSpec) Validate() error {
+ if len(w.WorkflowID) != workflowIDLen {
+ return fmt.Errorf("incorrect length for id %s: expected %d, got %d", w.WorkflowID, workflowIDLen, len(w.WorkflowID))
+ }
+
+ if len(w.WorkflowOwner) != workflowOwnerLen {
+ return fmt.Errorf("incorrect length for owner %s: expected %d, got %d", w.WorkflowOwner, workflowOwnerLen, len(w.WorkflowOwner))
+ }
+
+ return nil
+}
diff --git a/core/services/job/orm.go b/core/services/job/orm.go
index c05e944ea1e..9d2a6545163 100644
--- a/core/services/job/orm.go
+++ b/core/services/job/orm.go
@@ -75,7 +75,7 @@ type ORM interface {
FindJobWithoutSpecErrors(id int32) (jb Job, err error)
FindTaskResultByRunIDAndTaskName(runID int64, taskName string, qopts ...pg.QOpt) ([]byte, error)
- AssertBridgesExist(p pipeline.Pipeline) error
+ AssertBridgesExist(ctx context.Context, p pipeline.Pipeline) error
}
type ORMConfig interface {
@@ -108,7 +108,7 @@ func (o *orm) Close() error {
return nil
}
-func (o *orm) AssertBridgesExist(p pipeline.Pipeline) error {
+func (o *orm) AssertBridgesExist(ctx context.Context, p pipeline.Pipeline) error {
var bridgeNames = make(map[bridges.BridgeName]struct{})
var uniqueBridges []bridges.BridgeName
for _, task := range p.Tasks {
@@ -127,7 +127,7 @@ func (o *orm) AssertBridgesExist(p pipeline.Pipeline) error {
}
}
if len(uniqueBridges) != 0 {
- _, err := o.bridgeORM.FindBridges(uniqueBridges)
+ _, err := o.bridgeORM.FindBridges(ctx, uniqueBridges)
if err != nil {
return err
}
@@ -141,7 +141,8 @@ func (o *orm) AssertBridgesExist(p pipeline.Pipeline) error {
func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
q := o.q.WithOpts(qopts...)
p := jb.Pipeline
- if err := o.AssertBridgesExist(p); err != nil {
+ ctx := context.TODO() // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887
+ if err := o.AssertBridgesExist(ctx, p); err != nil {
return err
}
@@ -278,7 +279,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
if err2 != nil {
return err2
}
- if err2 = o.AssertBridgesExist(*feePipeline); err2 != nil {
+ if err2 = o.AssertBridgesExist(ctx, *feePipeline); err2 != nil {
return err2
}
}
@@ -443,12 +444,19 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
case Stream:
// 'stream' type has no associated spec, nothing to do here
case Workflow:
- // 'workflow' type has no associated spec, nothing to do here
+ var specID int32
+ sql := `INSERT INTO workflow_specs (workflow, workflow_id, workflow_owner, created_at, updated_at)
+ VALUES (:workflow, :workflow_id, :workflow_owner, NOW(), NOW())
+ RETURNING id;`
+ if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.WorkflowSpec); err != nil {
+ return errors.Wrap(err, "failed to create WorkflowSpec for jobSpec")
+ }
+ jb.WorkflowSpecID = &specID
default:
o.lggr.Panicf("Unsupported jb.Type: %v", jb.Type)
}
- pipelineSpecID, err := o.pipelineORM.CreateSpec(p, jb.MaxTaskDuration, pg.WithQueryer(tx))
+ pipelineSpecID, err := o.pipelineORM.CreateSpec(ctx, tx, p, jb.MaxTaskDuration)
if err != nil {
return errors.Wrap(err, "failed to create pipeline spec")
}
@@ -541,18 +549,18 @@ func (o *orm) InsertJob(job *Job, qopts ...pg.QOpt) error {
if job.ID == 0 {
query = `INSERT INTO jobs (name, stream_id, schema_version, type, max_task_duration, ocr_oracle_spec_id, ocr2_oracle_spec_id, direct_request_spec_id, flux_monitor_spec_id,
keeper_spec_id, cron_spec_id, vrf_spec_id, webhook_spec_id, blockhash_store_spec_id, bootstrap_spec_id, block_header_feeder_spec_id, gateway_spec_id,
- legacy_gas_station_server_spec_id, legacy_gas_station_sidecar_spec_id, external_job_id, gas_limit, forwarding_allowed, created_at)
+ legacy_gas_station_server_spec_id, legacy_gas_station_sidecar_spec_id, workflow_spec_id, external_job_id, gas_limit, forwarding_allowed, created_at)
VALUES (:name, :stream_id, :schema_version, :type, :max_task_duration, :ocr_oracle_spec_id, :ocr2_oracle_spec_id, :direct_request_spec_id, :flux_monitor_spec_id,
:keeper_spec_id, :cron_spec_id, :vrf_spec_id, :webhook_spec_id, :blockhash_store_spec_id, :bootstrap_spec_id, :block_header_feeder_spec_id, :gateway_spec_id,
- :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW())
+ :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :workflow_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW())
RETURNING *;`
} else {
query = `INSERT INTO jobs (id, name, stream_id, schema_version, type, max_task_duration, ocr_oracle_spec_id, ocr2_oracle_spec_id, direct_request_spec_id, flux_monitor_spec_id,
keeper_spec_id, cron_spec_id, vrf_spec_id, webhook_spec_id, blockhash_store_spec_id, bootstrap_spec_id, block_header_feeder_spec_id, gateway_spec_id,
- legacy_gas_station_server_spec_id, legacy_gas_station_sidecar_spec_id, external_job_id, gas_limit, forwarding_allowed, created_at)
+ legacy_gas_station_server_spec_id, legacy_gas_station_sidecar_spec_id, workflow_spec_id, external_job_id, gas_limit, forwarding_allowed, created_at)
VALUES (:id, :name, :stream_id, :schema_version, :type, :max_task_duration, :ocr_oracle_spec_id, :ocr2_oracle_spec_id, :direct_request_spec_id, :flux_monitor_spec_id,
:keeper_spec_id, :cron_spec_id, :vrf_spec_id, :webhook_spec_id, :blockhash_store_spec_id, :bootstrap_spec_id, :block_header_feeder_spec_id, :gateway_spec_id,
- :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW())
+ :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :workflow_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW())
RETURNING *;`
}
err := q.GetNamed(query, job, job)
@@ -590,7 +598,8 @@ func (o *orm) DeleteJob(id int32, qopts ...pg.QOpt) error {
blockhash_store_spec_id,
bootstrap_spec_id,
block_header_feeder_spec_id,
- gateway_spec_id
+ gateway_spec_id,
+ workflow_spec_id
),
deleted_oracle_specs AS (
DELETE FROM ocr_oracle_specs WHERE id IN (SELECT ocr_oracle_spec_id FROM deleted_jobs)
@@ -628,6 +637,9 @@ func (o *orm) DeleteJob(id int32, qopts ...pg.QOpt) error {
deleted_gateway_specs AS (
DELETE FROM gateway_specs WHERE id IN (SELECT gateway_spec_id FROM deleted_jobs)
),
+ deleted_workflow_specs AS (
+ DELETE FROM workflow_specs WHERE id in (SELECT workflow_spec_id FROM deleted_jobs)
+ ),
deleted_job_pipeline_specs AS (
DELETE FROM job_pipeline_specs WHERE job_id IN (SELECT id FROM deleted_jobs) RETURNING pipeline_spec_id
)
@@ -1284,6 +1296,7 @@ func LoadAllJobTypes(tx pg.Queryer, job *Job) error {
loadJobType(tx, job, "LegacyGasStationSidecarSpec", "legacy_gas_station_sidecar_specs", job.LegacyGasStationSidecarSpecID),
loadJobType(tx, job, "BootstrapSpec", "bootstrap_specs", job.BootstrapSpecID),
loadJobType(tx, job, "GatewaySpec", "gateway_specs", job.GatewaySpecID),
+ loadJobType(tx, job, "WorkflowSpec", "workflow_specs", job.WorkflowSpecID),
)
}
diff --git a/core/services/job/runner_integration_test.go b/core/services/job/runner_integration_test.go
index 110d4a41a91..6149bb71cf6 100644
--- a/core/services/job/runner_integration_test.go
+++ b/core/services/job/runner_integration_test.go
@@ -80,10 +80,10 @@ func TestRunner(t *testing.T) {
ethClient.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(nil, nil)
ctx := testutils.Context(t)
- pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
+ pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns())
require.NoError(t, pipelineORM.Start(ctx))
t.Cleanup(func() { assert.NoError(t, pipelineORM.Close()) })
- btORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
+ btORM := bridges.NewORM(db)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore})
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
c := clhttptest.NewTestLocalOnlyHTTPClient()
@@ -116,8 +116,8 @@ func TestRunner(t *testing.T) {
mockHTTP := cltest.NewHTTPMockServer(t, http.StatusOK, "POST", `{"turnout": 61.942}`)
httpURL = mockHTTP.URL
- _, bridgeER := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: mockElectionWinner.URL}, config.Database())
- _, bridgeVT := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: mockVoterTurnout.URL}, config.Database())
+ _, bridgeER := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: mockElectionWinner.URL})
+ _, bridgeVT := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: mockVoterTurnout.URL})
// Need a job in order to create a run
jb := MakeVoterTurnoutOCRJobSpecWithHTTPURL(t, transmitterAddress, httpURL, bridgeVT.Name.String(), bridgeER.Name.String())
@@ -169,7 +169,7 @@ func TestRunner(t *testing.T) {
})
t.Run("must delete job before deleting bridge", func(t *testing.T) {
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
jb := makeOCRJobSpecFromToml(t, fmt.Sprintf(`
type = "offchainreporting"
schemaVersion = 1
@@ -193,7 +193,7 @@ func TestRunner(t *testing.T) {
t.Run("referencing a non-existent bridge should error", func(t *testing.T) {
// Create a random bridge name
- _, b := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, b := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
// Reference a different one
legacyChains := cltest.NewLegacyChainsWithMockChain(t, nil, config)
@@ -846,7 +846,7 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) {
require.NoError(t, err)
bridgeCalled <- struct{}{}
}))
- _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: bridgeServer.URL}, app.GetConfig().Database())
+ _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: bridgeServer.URL})
bridgeName = bridge.Name.String()
defer bridgeServer.Close()
}
@@ -888,8 +888,8 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) {
_ = cltest.CreateJobRunViaExternalInitiatorV2(t, app, jobUUID, *eia, cltest.MustJSONMarshal(t, eiRequest))
- pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database())
+ pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(app.GetSqlxDB())
jobORM := NewTestORM(t, app.GetSqlxDB(), pipelineORM, bridgesORM, app.KeyStore, cfg.Database())
// Trigger v2/resume
@@ -1025,7 +1025,7 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) {
require.NoError(t, err)
bridgeCalled <- struct{}{}
}))
- _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: bridgeServer.URL}, app.GetConfig().Database())
+ _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: bridgeServer.URL})
bridgeName = bridge.Name.String()
defer bridgeServer.Close()
}
@@ -1065,8 +1065,8 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) {
t.Run("simulate request from EI -> Core node with erroring callback", func(t *testing.T) {
_ = cltest.CreateJobRunViaExternalInitiatorV2(t, app, jobUUID, *eia, cltest.MustJSONMarshal(t, eiRequest))
- pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.Database())
+ pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(app.GetSqlxDB())
jobORM := NewTestORM(t, app.GetSqlxDB(), pipelineORM, bridgesORM, app.KeyStore, cfg.Database())
// Trigger v2/resume
diff --git a/core/services/job/spawner.go b/core/services/job/spawner.go
index 3d30a3190b3..8024424226c 100644
--- a/core/services/job/spawner.go
+++ b/core/services/job/spawner.go
@@ -78,7 +78,7 @@ type (
// non-db side effects. This is required in order to guarantee mutual atomicity between
// all tasks intended to happen during job deletion. For the same reason, the job will
// not show up in the db within OnDeleteJob(), even though it is still actively running.
- OnDeleteJob(ctx context.Context, jb Job, q pg.Queryer) error
+ OnDeleteJob(ctx context.Context, jb Job) error
}
activeJob struct {
@@ -340,7 +340,7 @@ func (js *spawner) DeleteJob(jobID int32, qopts ...pg.QOpt) error {
// we know the DELETE will succeed. The DELETE will be finalized only if all db transactions in OnDeleteJob()
// succeed. If either of those fails, the job will not be stopped and everything will be rolled back.
lggr.Debugw("Callback: OnDeleteJob")
- err = aj.delegate.OnDeleteJob(ctx, aj.spec, tx)
+ err = aj.delegate.OnDeleteJob(ctx, aj.spec)
if err != nil {
return err
}
@@ -395,7 +395,9 @@ func (n *NullDelegate) ServicesForSpec(ctx context.Context, spec Job) (s []Servi
return
}
-func (n *NullDelegate) BeforeJobCreated(spec Job) {}
-func (n *NullDelegate) AfterJobCreated(spec Job) {}
-func (n *NullDelegate) BeforeJobDeleted(spec Job) {}
-func (n *NullDelegate) OnDeleteJob(ctx context.Context, spec Job, q pg.Queryer) error { return nil }
+func (n *NullDelegate) BeforeJobCreated(spec Job) {}
+func (n *NullDelegate) AfterJobCreated(spec Job) {}
+func (n *NullDelegate) BeforeJobDeleted(spec Job) {}
+func (n *NullDelegate) OnDeleteJob(context.Context, Job) error {
+ return nil
+}
diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go
index ac0783e9868..802763cfaab 100644
--- a/core/services/job/spawner_test.go
+++ b/core/services/job/spawner_test.go
@@ -85,8 +85,8 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
require.NoError(t, keyStore.OCR2().Add(cltest.DefaultOCR2Key))
_, address := cltest.MustInsertRandomKey(t, ethKeyStore)
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
+ _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{})
ethClient := cltest.NewEthMocksWithDefaultChain(t)
ethClient.On("CallContext", mock.Anything, mock.Anything, "eth_getBlockByNumber", mock.Anything, false).
@@ -100,7 +100,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
t.Run("should respect its dependents", func(t *testing.T) {
lggr := logger.TestLogger(t)
- orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database())
+ orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database())
a := utils.NewDependentAwaiter()
a.AddDependents(1)
spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{}, db, lggr, []utils.DependentAwaiter{a})
@@ -123,7 +123,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
jobB := makeOCRJobSpec(t, address, bridge.Name.String(), bridge2.Name.String())
lggr := logger.TestLogger(t)
- orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database())
+ orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database())
eventuallyA := cltest.NewAwaiter()
serviceA1 := mocks.NewServiceCtx(t)
@@ -188,7 +188,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
serviceA2.On("Start", mock.Anything).Return(nil).Once().Run(func(mock.Arguments) { eventually.ItHappened() })
lggr := logger.TestLogger(t)
- orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database())
+ orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database())
mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t))
d := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config.Database(), mailMon)
delegateA := &delegate{jobA.Type, []job.ServiceCtx{serviceA1, serviceA2}, 0, nil, d}
@@ -222,7 +222,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
serviceA2.On("Start", mock.Anything).Return(nil).Once().Run(func(mock.Arguments) { eventuallyStart.ItHappened() })
lggr := logger.TestLogger(t)
- orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database())
+ orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database())
mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t))
d := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config.Database(), mailMon)
delegateA := &delegate{jobA.Type, []job.ServiceCtx{serviceA1, serviceA2}, 0, nil, d}
@@ -300,13 +300,13 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
jobOCR2VRF := makeOCR2VRFJobSpec(t, keyStore, config, address, chain.ID(), 2)
- orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database())
+ orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database())
mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t))
processConfig := plugins.NewRegistrarConfig(loop.GRPCOpts{}, func(name string) (*plugins.RegisteredLoop, error) { return nil, nil }, func(loopId string) {})
ocr2DelegateConfig := ocr2.NewDelegateConfig(config.OCR2(), config.Mercury(), config.Threshold(), config.Insecure(), config.JobPipeline(), config.Database(), processConfig)
- d := ocr2.NewDelegate(nil, orm, nil, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig,
+ d := ocr2.NewDelegate(nil, nil, orm, nil, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig,
keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon, capabilities.NewRegistry(lggr))
delegateOCR2 := &delegate{jobOCR2VRF.Type, []job.ServiceCtx{}, 0, nil, d}
diff --git a/core/services/keeper/delegate.go b/core/services/keeper/delegate.go
index 8cadb8cd77f..9652434759b 100644
--- a/core/services/keeper/delegate.go
+++ b/core/services/keeper/delegate.go
@@ -11,7 +11,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
)
@@ -51,10 +50,10 @@ func (d *Delegate) JobType() job.Type {
return job.Keeper
}
-func (d *Delegate) BeforeJobCreated(spec job.Job) {}
-func (d *Delegate) AfterJobCreated(spec job.Job) {}
-func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) BeforeJobCreated(spec job.Job) {}
+func (d *Delegate) AfterJobCreated(spec job.Job) {}
+func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec satisfies the job.Delegate interface.
func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services []job.ServiceCtx, err error) {
@@ -66,7 +65,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services
return nil, err
}
registryAddress := spec.KeeperSpec.ContractAddress
- orm := NewORM(d.db, d.logger, chain.Config().Database())
+ orm := NewORM(d.db, d.logger)
svcLogger := d.logger.With(
"jobID", spec.ID,
"registryAddress", registryAddress.Hex(),
diff --git a/core/services/keeper/helpers_test.go b/core/services/keeper/helpers_test.go
index fdcb12b01b1..3fb9d7760a4 100644
--- a/core/services/keeper/helpers_test.go
+++ b/core/services/keeper/helpers_test.go
@@ -1,14 +1,15 @@
package keeper
import (
+ "context"
"math/big"
"github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
)
-func (rs *RegistrySynchronizer) ExportedFullSync() {
- rs.fullSync()
+func (rs *RegistrySynchronizer) ExportedFullSync(ctx context.Context) {
+ rs.fullSync(ctx)
}
func (rw *RegistryWrapper) GetUpkeepIdFromRawRegistrationLog(rawLog types.Log) (*big.Int, error) {
diff --git a/core/services/keeper/integration_test.go b/core/services/keeper/integration_test.go
index d78b1fb2ca5..08699d3d835 100644
--- a/core/services/keeper/integration_test.go
+++ b/core/services/keeper/integration_test.go
@@ -32,7 +32,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
@@ -176,6 +175,7 @@ func TestKeeperEthIntegration(t *testing.T) {
test := tt
t.Run(test.name, func(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
// setup node key
@@ -247,16 +247,15 @@ func TestKeeperEthIntegration(t *testing.T) {
c.EVM[0].MinIncomingConfirmations = ptr[uint32](1) // disable reorg protection for this test
c.EVM[0].HeadTracker.MaxBufferSize = ptr[uint32](100) // helps prevent missed heads
})
- scopedConfig := evmtest.NewChainScopedConfig(t, config)
- korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
+ korm := keeper.NewORM(db, logger.TestLogger(t))
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, backend.Backend(), nodeKey)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// create job
regAddrEIP55 := evmtypes.EIP55AddressFromAddress(regAddr)
job := cltest.MustInsertKeeperJob(t, db, korm, nodeAddressEIP55, regAddrEIP55)
- err = app.JobSpawner().StartService(testutils.Context(t), job)
+ err = app.JobSpawner().StartService(ctx, job)
require.NoError(t, err)
// keeper job is triggered and payload is received
@@ -313,7 +312,7 @@ func TestKeeperEthIntegration(t *testing.T) {
cltest.AssertRecordEventually(t, app.GetSqlxDB(), ®istry, fmt.Sprintf("SELECT * FROM keeper_registries WHERE id = %d", registry.ID), func() bool {
return registry.KeeperIndex == -1
})
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
// Since we set grace period to 0, we can have more than 1 pipeline run per perform
// This happens in case we start a pipeline run before previous perform tx is committed to chain
@@ -328,6 +327,7 @@ func TestKeeperEthIntegration(t *testing.T) {
func TestKeeperForwarderEthIntegration(t *testing.T) {
t.Parallel()
t.Run("keeper_forwarder_flow", func(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
// setup node key
@@ -407,15 +407,14 @@ func TestKeeperForwarderEthIntegration(t *testing.T) {
c.EVM[0].Transactions.ForwardersEnabled = ptr(true) // Enable Operator Forwarder flow
c.EVM[0].ChainID = (*ubig.Big)(testutils.SimulatedChainID)
})
- scopedConfig := evmtest.NewChainScopedConfig(t, config)
- korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
+ korm := keeper.NewORM(db, logger.TestLogger(t))
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, backend.Backend(), nodeKey)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
forwarderORM := forwarders.NewORM(db)
chainID := ubig.Big(*backend.ConfiguredChainID())
- _, err = forwarderORM.CreateForwarder(testutils.Context(t), fwdrAddress, chainID)
+ _, err = forwarderORM.CreateForwarder(ctx, fwdrAddress, chainID)
require.NoError(t, err)
addr, err := app.GetRelayers().LegacyEVMChains().Slice()[0].TxManager().GetForwarderForEOA(nodeAddress)
@@ -452,7 +451,7 @@ func TestKeeperForwarderEthIntegration(t *testing.T) {
evmtypes.EIP55AddressFromAddress(nelly.From): 1,
},
}
- err = korm.UpsertRegistry(®istry)
+ err = korm.UpsertRegistry(ctx, ®istry)
require.NoError(t, err)
callOpts := bind.CallOpts{From: nodeAddress}
@@ -464,7 +463,7 @@ func TestKeeperForwarderEthIntegration(t *testing.T) {
}
require.Equal(t, lastKeeper(), common.Address{})
- err = app.JobSpawner().StartService(testutils.Context(t), jb)
+ err = app.JobSpawner().StartService(ctx, jb)
require.NoError(t, err)
// keeper job is triggered and payload is received
@@ -483,6 +482,7 @@ func TestKeeperForwarderEthIntegration(t *testing.T) {
func TestMaxPerformDataSize(t *testing.T) {
t.Parallel()
t.Run("max_perform_data_size_test", func(t *testing.T) {
+ ctx := testutils.Context(t)
maxPerformDataSize := 1000 // Will be set as config override
g := gomega.NewWithT(t)
@@ -551,16 +551,15 @@ func TestMaxPerformDataSize(t *testing.T) {
c.EVM[0].MinIncomingConfirmations = ptr[uint32](1) // disable reorg protection for this test
c.EVM[0].HeadTracker.MaxBufferSize = ptr[uint32](100) // helps prevent missed heads
})
- scopedConfig := evmtest.NewChainScopedConfig(t, config)
- korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
+ korm := keeper.NewORM(db, logger.TestLogger(t))
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, backend.Backend(), nodeKey)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// create job
regAddrEIP55 := evmtypes.EIP55AddressFromAddress(regAddr)
job := cltest.MustInsertKeeperJob(t, db, korm, nodeAddressEIP55, regAddrEIP55)
- err = app.JobSpawner().StartService(testutils.Context(t), job)
+ err = app.JobSpawner().StartService(ctx, job)
require.NoError(t, err)
// keeper job is triggered
diff --git a/core/services/keeper/orm.go b/core/services/keeper/orm.go
index 55dd6c52e68..ed3196bb660 100644
--- a/core/services/keeper/orm.go
+++ b/core/services/keeper/orm.go
@@ -1,60 +1,60 @@
package keeper
import (
+ "context"
"math/rand"
- "github.com/jmoiron/sqlx"
"github.com/lib/pq"
"github.com/pkg/errors"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
// ORM implements ORM layer using PostgreSQL
type ORM struct {
- q pg.Q
+ ds sqlutil.DataSource
logger logger.Logger
}
// NewORM is the constructor of postgresORM
-func NewORM(db *sqlx.DB, lggr logger.Logger, config pg.QConfig) ORM {
+func NewORM(ds sqlutil.DataSource, lggr logger.Logger) *ORM {
lggr = lggr.Named("KeeperORM")
- return ORM{
- q: pg.NewQ(db, lggr, config),
+ return &ORM{
+ ds: ds,
logger: lggr,
}
}
-func (korm ORM) Q() pg.Q {
- return korm.q
+func (o *ORM) DataSource() sqlutil.DataSource {
+ return o.ds
}
// Registries returns all registries
-func (korm ORM) Registries() ([]Registry, error) {
+func (o *ORM) Registries(ctx context.Context) ([]Registry, error) {
var registries []Registry
- err := korm.q.Select(®istries, `SELECT * FROM keeper_registries ORDER BY id ASC`)
+ err := o.ds.SelectContext(ctx, ®istries, `SELECT * FROM keeper_registries ORDER BY id ASC`)
return registries, errors.Wrap(err, "failed to get registries")
}
// RegistryByContractAddress returns a single registry based on provided address
-func (korm ORM) RegistryByContractAddress(registryAddress types.EIP55Address) (Registry, error) {
+func (o *ORM) RegistryByContractAddress(ctx context.Context, registryAddress types.EIP55Address) (Registry, error) {
var registry Registry
- err := korm.q.Get(®istry, `SELECT * FROM keeper_registries WHERE keeper_registries.contract_address = $1`, registryAddress)
+ err := o.ds.GetContext(ctx, ®istry, `SELECT * FROM keeper_registries WHERE keeper_registries.contract_address = $1`, registryAddress)
return registry, errors.Wrap(err, "failed to get registry")
}
// RegistryForJob returns a specific registry for a job with the given ID
-func (korm ORM) RegistryForJob(jobID int32) (Registry, error) {
+func (o *ORM) RegistryForJob(ctx context.Context, jobID int32) (Registry, error) {
var registry Registry
- err := korm.q.Get(®istry, `SELECT * FROM keeper_registries WHERE job_id = $1 LIMIT 1`, jobID)
+ err := o.ds.GetContext(ctx, ®istry, `SELECT * FROM keeper_registries WHERE job_id = $1 LIMIT 1`, jobID)
return registry, errors.Wrapf(err, "failed to get registry with job_id %d", jobID)
}
// UpsertRegistry upserts registry by the given input
-func (korm ORM) UpsertRegistry(registry *Registry) error {
+func (o *ORM) UpsertRegistry(ctx context.Context, registry *Registry) error {
stmt := `
INSERT INTO keeper_registries (job_id, keeper_index, contract_address, from_address, check_gas, block_count_per_turn, num_keepers, keeper_index_map) VALUES (
:job_id, :keeper_index, :contract_address, :from_address, :check_gas, :block_count_per_turn, :num_keepers, :keeper_index_map
@@ -66,12 +66,16 @@ INSERT INTO keeper_registries (job_id, keeper_index, contract_address, from_addr
keeper_index_map = :keeper_index_map
RETURNING *
`
- err := korm.q.GetNamed(stmt, registry, registry)
+ query, args, err := o.ds.BindNamed(stmt, registry)
+ if err != nil {
+ return errors.Wrap(err, "failed to upsert registry")
+ }
+ err = o.ds.GetContext(ctx, registry, query, args...)
return errors.Wrap(err, "failed to upsert registry")
}
// UpsertUpkeep upserts upkeep by the given input
-func (korm ORM) UpsertUpkeep(registration *UpkeepRegistration) error {
+func (o *ORM) UpsertUpkeep(ctx context.Context, registration *UpkeepRegistration) error {
stmt := `
INSERT INTO upkeep_registrations (registry_id, execute_gas, check_data, upkeep_id, positioning_constant, last_run_block_height) VALUES (
:registry_id, :execute_gas, :check_data, :upkeep_id, :positioning_constant, :last_run_block_height
@@ -81,13 +85,17 @@ INSERT INTO upkeep_registrations (registry_id, execute_gas, check_data, upkeep_i
positioning_constant = :positioning_constant
RETURNING *
`
- err := korm.q.GetNamed(stmt, registration, registration)
+ query, args, err := o.ds.BindNamed(stmt, registration)
+ if err != nil {
+ return errors.Wrap(err, "failed to upsert upkeep")
+ }
+ err = o.ds.GetContext(ctx, registration, query, args...)
return errors.Wrap(err, "failed to upsert upkeep")
}
// UpdateUpkeepLastKeeperIndex updates the last keeper index for an upkeep
-func (korm ORM) UpdateUpkeepLastKeeperIndex(jobID int32, upkeepID *big.Big, fromAddress types.EIP55Address) error {
- _, err := korm.q.Exec(`
+func (o *ORM) UpdateUpkeepLastKeeperIndex(ctx context.Context, jobID int32, upkeepID *big.Big, fromAddress types.EIP55Address) error {
+ _, err := o.ds.ExecContext(ctx, `
UPDATE upkeep_registrations
SET
last_keeper_index = CAST((SELECT keeper_index_map -> $3 FROM keeper_registries WHERE job_id = $1) AS int)
@@ -98,12 +106,12 @@ func (korm ORM) UpdateUpkeepLastKeeperIndex(jobID int32, upkeepID *big.Big, from
}
// BatchDeleteUpkeepsForJob deletes all upkeeps by the given IDs for the job with the given ID
-func (korm ORM) BatchDeleteUpkeepsForJob(jobID int32, upkeepIDs []big.Big) (int64, error) {
+func (o *ORM) BatchDeleteUpkeepsForJob(ctx context.Context, jobID int32, upkeepIDs []big.Big) (int64, error) {
strIds := []string{}
for _, upkeepID := range upkeepIDs {
strIds = append(strIds, upkeepID.String())
}
- res, err := korm.q.Exec(`
+ res, err := o.ds.ExecContext(ctx, `
DELETE FROM upkeep_registrations WHERE registry_id IN (
SELECT id FROM keeper_registries WHERE job_id = $1
) AND upkeep_id = ANY($2)
@@ -125,7 +133,7 @@ DELETE FROM upkeep_registrations WHERE registry_id IN (
// -- OR is it my buddy's turn AND they were the last keeper to do the perform for this upkeep
// DEV: note we cast upkeep_id and binaryHash as 32 bits, even though both are 256 bit numbers when performing XOR. This is enough information
// to distribute the upkeeps over the keepers so long as num keepers < 4294967296
-func (korm ORM) EligibleUpkeepsForRegistry(registryAddress types.EIP55Address, blockNumber int64, gracePeriod int64, binaryHash string) (upkeeps []UpkeepRegistration, err error) {
+func (o *ORM) EligibleUpkeepsForRegistry(ctx context.Context, registryAddress types.EIP55Address, blockNumber int64, gracePeriod int64, binaryHash string) (upkeeps []UpkeepRegistration, err error) {
stmt := `
SELECT upkeep_registrations.*
FROM upkeep_registrations
@@ -165,10 +173,10 @@ WHERE keeper_registries.contract_address = $1
)
)
`
- if err = korm.q.Select(&upkeeps, stmt, registryAddress, gracePeriod, blockNumber, binaryHash); err != nil {
+ if err = o.ds.SelectContext(ctx, &upkeeps, stmt, registryAddress, gracePeriod, blockNumber, binaryHash); err != nil {
return upkeeps, errors.Wrap(err, "EligibleUpkeepsForRegistry failed to get upkeep_registrations")
}
- if err = loadUpkeepsRegistry(korm.q, upkeeps); err != nil {
+ if err = o.loadUpkeepsRegistry(ctx, upkeeps); err != nil {
return upkeeps, errors.Wrap(err, "EligibleUpkeepsForRegistry failed to load Registry on upkeeps")
}
@@ -179,7 +187,7 @@ WHERE keeper_registries.contract_address = $1
return upkeeps, err
}
-func loadUpkeepsRegistry(q pg.Queryer, upkeeps []UpkeepRegistration) error {
+func (o *ORM) loadUpkeepsRegistry(ctx context.Context, upkeeps []UpkeepRegistration) error {
registryIDM := make(map[int64]*Registry)
var registryIDs []int64
for _, upkeep := range upkeeps {
@@ -189,7 +197,7 @@ func loadUpkeepsRegistry(q pg.Queryer, upkeeps []UpkeepRegistration) error {
}
}
var registries []*Registry
- err := q.Select(®istries, `SELECT * FROM keeper_registries WHERE id = ANY($1)`, pq.Array(registryIDs))
+ err := o.ds.SelectContext(ctx, ®istries, `SELECT * FROM keeper_registries WHERE id = ANY($1)`, pq.Array(registryIDs))
if err != nil {
return errors.Wrap(err, "loadUpkeepsRegistry failed")
}
@@ -202,8 +210,8 @@ func loadUpkeepsRegistry(q pg.Queryer, upkeeps []UpkeepRegistration) error {
return nil
}
-func (korm ORM) AllUpkeepIDsForRegistry(regID int64) (upkeeps []big.Big, err error) {
- err = korm.q.Select(&upkeeps, `
+func (o *ORM) AllUpkeepIDsForRegistry(ctx context.Context, regID int64) (upkeeps []big.Big, err error) {
+ err = o.ds.SelectContext(ctx, &upkeeps, `
SELECT upkeep_id
FROM upkeep_registrations
WHERE registry_id = $1
@@ -212,8 +220,8 @@ WHERE registry_id = $1
}
// SetLastRunInfoForUpkeepOnJob sets the last run block height and the associated keeper index only if the new block height is greater than the previous.
-func (korm ORM) SetLastRunInfoForUpkeepOnJob(jobID int32, upkeepID *big.Big, height int64, fromAddress types.EIP55Address, qopts ...pg.QOpt) (int64, error) {
- res, err := korm.q.WithOpts(qopts...).Exec(`
+func (o *ORM) SetLastRunInfoForUpkeepOnJob(ctx context.Context, jobID int32, upkeepID *big.Big, height int64, fromAddress types.EIP55Address) (int64, error) {
+ res, err := o.ds.ExecContext(ctx, `
UPDATE upkeep_registrations
SET last_run_block_height = $1,
last_keeper_index = CAST((SELECT keeper_index_map -> $4 FROM keeper_registries WHERE job_id = $3) AS int)
diff --git a/core/services/keeper/orm_test.go b/core/services/keeper/orm_test.go
index ed58554ef0d..1e5d927fe2f 100644
--- a/core/services/keeper/orm_test.go
+++ b/core/services/keeper/orm_test.go
@@ -19,6 +19,7 @@ import (
evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "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"
@@ -36,12 +37,12 @@ var (
func setupKeeperDB(t *testing.T) (
*sqlx.DB,
evmconfig.ChainScopedConfig,
- keeper.ORM,
+ *keeper.ORM,
) {
gcfg := configtest.NewGeneralConfig(t, nil)
db := pgtest.NewSqlxDB(t)
cfg := evmtest.NewChainScopedConfig(t, gcfg)
- orm := keeper.NewORM(db, logger.TestLogger(t), cfg.Database())
+ orm := keeper.NewORM(db, logger.TestLogger(t))
return db, cfg, orm
}
@@ -74,32 +75,35 @@ func assertLastRunHeight(t *testing.T, db *sqlx.DB, upkeep keeper.UpkeepRegistra
func TestKeeperDB_Registries(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
- existingRegistries, err := orm.Registries()
+ existingRegistries, err := orm.Registries(ctx)
require.NoError(t, err)
require.Equal(t, 2, len(existingRegistries))
}
func TestKeeperDB_RegistryByContractAddress(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
- registryByContractAddress, err := orm.RegistryByContractAddress(registry.ContractAddress)
+ registryByContractAddress, err := orm.RegistryByContractAddress(ctx, registry.ContractAddress)
require.NoError(t, err)
require.Equal(t, registry, registryByContractAddress)
}
func TestKeeperDB_UpsertUpkeep(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
@@ -113,7 +117,7 @@ func TestKeeperDB_UpsertUpkeep(t *testing.T) {
LastRunBlockHeight: 1,
PositioningConstant: 1,
}
- require.NoError(t, orm.UpsertUpkeep(&upkeep))
+ require.NoError(t, orm.UpsertUpkeep(ctx, &upkeep))
cltest.AssertCount(t, db, "upkeep_registrations", 1)
// update upkeep
@@ -121,7 +125,7 @@ func TestKeeperDB_UpsertUpkeep(t *testing.T) {
upkeep.CheckData = common.Hex2Bytes("8888")
upkeep.LastRunBlockHeight = 2
- err := orm.UpsertUpkeep(&upkeep)
+ err := orm.UpsertUpkeep(ctx, &upkeep)
require.NoError(t, err)
cltest.AssertCount(t, db, "upkeep_registrations", 1)
@@ -135,21 +139,22 @@ func TestKeeperDB_UpsertUpkeep(t *testing.T) {
func TestKeeperDB_BatchDeleteUpkeepsForJob(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, job := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
- expectedUpkeepID := cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry).UpkeepID
+ expectedUpkeepID := cltest.MustInsertUpkeepForRegistry(t, db, registry).UpkeepID
var upkeepIDs []ubig.Big
for i := 0; i < 2; i++ {
- upkeep := cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry)
+ upkeep := cltest.MustInsertUpkeepForRegistry(t, db, registry)
upkeepIDs = append(upkeepIDs, *upkeep.UpkeepID)
}
cltest.AssertCount(t, db, "upkeep_registrations", 3)
- _, err := orm.BatchDeleteUpkeepsForJob(job.ID, upkeepIDs)
+ _, err := orm.BatchDeleteUpkeepsForJob(ctx, job.ID, upkeepIDs)
require.NoError(t, err)
cltest.AssertCount(t, db, "upkeep_registrations", 1)
@@ -161,6 +166,7 @@ func TestKeeperDB_BatchDeleteUpkeepsForJob(t *testing.T) {
func TestKeeperDB_EligibleUpkeeps_Shuffle(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
@@ -173,12 +179,12 @@ func TestKeeperDB_EligibleUpkeeps_Shuffle(t *testing.T) {
for i := 0; i < 100; i++ {
k := newUpkeep(registry, int64(i))
ordered[i] = int64(i)
- err := orm.UpsertUpkeep(&k)
+ err := orm.UpsertUpkeep(ctx, &k)
require.NoError(t, err)
}
cltest.AssertCount(t, db, "upkeep_registrations", 100)
- eligibleUpkeeps, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, blockheight, gracePeriod, fmt.Sprintf("%b", evmutils.NewHash().Big()))
+ eligibleUpkeeps, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, blockheight, gracePeriod, fmt.Sprintf("%b", evmutils.NewHash().Big()))
assert.NoError(t, err)
require.Len(t, eligibleUpkeeps, 100)
@@ -191,13 +197,14 @@ func TestKeeperDB_EligibleUpkeeps_Shuffle(t *testing.T) {
func TestKeeperDB_NewEligibleUpkeeps_GracePeriod(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 2, 20)
for i := 0; i < 100; i++ {
- cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry)
}
cltest.AssertCount(t, db, "keeper_registries", 1)
@@ -206,38 +213,39 @@ func TestKeeperDB_NewEligibleUpkeeps_GracePeriod(t *testing.T) {
// if current keeper index = 0 and all upkeeps last perform was done by index = 0 and still within grace period
upkeep := keeper.UpkeepRegistration{}
require.NoError(t, db.Get(&upkeep, `UPDATE upkeep_registrations SET last_keeper_index = 0, last_run_block_height = 10 RETURNING *`))
- list0, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 21, 100, fmt.Sprintf("%b", evmutils.NewHash().Big())) // none eligible
+ list0, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 21, 100, fmt.Sprintf("%b", evmutils.NewHash().Big())) // none eligible
require.NoError(t, err)
require.Equal(t, 0, len(list0), "should be 0 as all last perform was done by current node")
// once passed grace period
- list1, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 121, 100, fmt.Sprintf("%b", evmutils.NewHash().Big())) // none eligible
+ list1, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 121, 100, fmt.Sprintf("%b", evmutils.NewHash().Big())) // none eligible
require.NoError(t, err)
require.NotEqual(t, 0, len(list1), "should get some eligible upkeeps now that they are outside grace period")
}
func TestKeeperDB_EligibleUpkeeps_TurnsRandom(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 3, 10)
for i := 0; i < 1000; i++ {
- cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry)
}
cltest.AssertCount(t, db, "keeper_registries", 1)
cltest.AssertCount(t, db, "upkeep_registrations", 1000)
// 3 keepers 10 block turns should be different every turn
- list1, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 20, 100, fmt.Sprintf("%b", evmutils.NewHash().Big()))
+ list1, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 20, 100, fmt.Sprintf("%b", evmutils.NewHash().Big()))
require.NoError(t, err)
- list2, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 31, 100, fmt.Sprintf("%b", evmutils.NewHash().Big()))
+ list2, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 31, 100, fmt.Sprintf("%b", evmutils.NewHash().Big()))
require.NoError(t, err)
- list3, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 42, 100, fmt.Sprintf("%b", evmutils.NewHash().Big()))
+ list3, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 42, 100, fmt.Sprintf("%b", evmutils.NewHash().Big()))
require.NoError(t, err)
- list4, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 53, 100, fmt.Sprintf("%b", evmutils.NewHash().Big()))
+ list4, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 53, 100, fmt.Sprintf("%b", evmutils.NewHash().Big()))
require.NoError(t, err)
// sort before compare
@@ -261,13 +269,14 @@ func TestKeeperDB_EligibleUpkeeps_TurnsRandom(t *testing.T) {
func TestKeeperDB_NewEligibleUpkeeps_SkipIfLastPerformedByCurrentKeeper(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 2, 20)
for i := 0; i < 100; i++ {
- cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry)
}
cltest.AssertCount(t, db, "keeper_registries", 1)
@@ -276,20 +285,21 @@ func TestKeeperDB_NewEligibleUpkeeps_SkipIfLastPerformedByCurrentKeeper(t *testi
// if current keeper index = 0 and all upkeeps last perform was done by index = 0 then skip as it would not pass required turn taking
upkeep := keeper.UpkeepRegistration{}
require.NoError(t, db.Get(&upkeep, `UPDATE upkeep_registrations SET last_keeper_index = 0 RETURNING *`))
- list0, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 21, 100, fmt.Sprintf("%b", evmutils.NewHash().Big())) // none eligible
+ list0, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 21, 100, fmt.Sprintf("%b", evmutils.NewHash().Big())) // none eligible
require.NoError(t, err)
require.Equal(t, 0, len(list0), "should be 0 as all last perform was done by current node")
}
func TestKeeperDB_NewEligibleUpkeeps_CoverBuddy(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 1, 2, 20)
for i := 0; i < 100; i++ {
- cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry)
}
cltest.AssertCount(t, db, "keeper_registries", 1)
@@ -297,23 +307,24 @@ func TestKeeperDB_NewEligibleUpkeeps_CoverBuddy(t *testing.T) {
upkeep := keeper.UpkeepRegistration{}
binaryHash := fmt.Sprintf("%b", evmutils.NewHash().Big())
- listBefore, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 21, 100, binaryHash) // normal
+ listBefore, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 21, 100, binaryHash) // normal
require.NoError(t, err)
require.NoError(t, db.Get(&upkeep, `UPDATE upkeep_registrations SET last_keeper_index = 0 RETURNING *`))
- listAfter, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 21, 100, binaryHash) // covering buddy
+ listAfter, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 21, 100, binaryHash) // covering buddy
require.NoError(t, err)
require.Greater(t, len(listAfter), len(listBefore), "after our buddy runs all the performs we should have more eligible then a normal turn")
}
func TestKeeperDB_NewEligibleUpkeeps_FirstTurn(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 2, 20)
for i := 0; i < 100; i++ {
- cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry)
}
cltest.AssertCount(t, db, "keeper_registries", 1)
@@ -321,29 +332,30 @@ func TestKeeperDB_NewEligibleUpkeeps_FirstTurn(t *testing.T) {
binaryHash := fmt.Sprintf("%b", evmutils.NewHash().Big())
// last keeper index is null to simulate a normal first run
- listKpr0, err := orm.EligibleUpkeepsForRegistry(registry.ContractAddress, 21, 100, binaryHash) // someone eligible only kpr0 turn
+ listKpr0, err := orm.EligibleUpkeepsForRegistry(ctx, registry.ContractAddress, 21, 100, binaryHash) // someone eligible only kpr0 turn
require.NoError(t, err)
require.NotEqual(t, 0, len(listKpr0), "kpr0 should have some eligible as a normal turn")
}
func TestKeeperDB_NewEligibleUpkeeps_FiltersByRegistry(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry1, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
registry2, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
- cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry1)
- cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry2)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry1)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry2)
cltest.AssertCount(t, db, "keeper_registries", 2)
cltest.AssertCount(t, db, "upkeep_registrations", 2)
binaryHash := fmt.Sprintf("%b", evmutils.NewHash().Big())
- list1, err := orm.EligibleUpkeepsForRegistry(registry1.ContractAddress, 20, 100, binaryHash)
+ list1, err := orm.EligibleUpkeepsForRegistry(ctx, registry1.ContractAddress, 20, 100, binaryHash)
require.NoError(t, err)
- list2, err := orm.EligibleUpkeepsForRegistry(registry2.ContractAddress, 20, 100, binaryHash)
+ list2, err := orm.EligibleUpkeepsForRegistry(ctx, registry2.ContractAddress, 20, 100, binaryHash)
require.NoError(t, err)
assert.Equal(t, 1, len(list1))
@@ -352,25 +364,26 @@ func TestKeeperDB_NewEligibleUpkeeps_FiltersByRegistry(t *testing.T) {
func TestKeeperDB_AllUpkeepIDsForRegistry(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, _ := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
- upkeepIDs, err := orm.AllUpkeepIDsForRegistry(registry.ID)
+ upkeepIDs, err := orm.AllUpkeepIDsForRegistry(ctx, registry.ID)
require.NoError(t, err)
// No upkeeps returned
require.Len(t, upkeepIDs, 0)
upkeep := newUpkeep(registry, 3)
- err = orm.UpsertUpkeep(&upkeep)
+ err = orm.UpsertUpkeep(ctx, &upkeep)
require.NoError(t, err)
upkeep = newUpkeep(registry, 8)
- err = orm.UpsertUpkeep(&upkeep)
+ err = orm.UpsertUpkeep(ctx, &upkeep)
require.NoError(t, err)
// We should get two upkeeps IDs, 3 & 8
- upkeepIDs, err = orm.AllUpkeepIDsForRegistry(registry.ID)
+ upkeepIDs, err = orm.AllUpkeepIDsForRegistry(ctx, registry.ID)
require.NoError(t, err)
// No upkeeps returned
require.Len(t, upkeepIDs, 2)
@@ -380,12 +393,13 @@ func TestKeeperDB_AllUpkeepIDsForRegistry(t *testing.T) {
func TestKeeperDB_UpdateUpkeepLastKeeperIndex(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, j := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
- upkeep := cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry)
+ upkeep := cltest.MustInsertUpkeepForRegistry(t, db, registry)
- require.NoError(t, orm.UpdateUpkeepLastKeeperIndex(j.ID, upkeep.UpkeepID, registry.FromAddress))
+ require.NoError(t, orm.UpdateUpkeepLastKeeperIndex(ctx, j.ID, upkeep.UpkeepID, registry.FromAddress))
err := db.Get(&upkeep, `SELECT * FROM upkeep_registrations WHERE upkeep_id = $1`, upkeep.UpkeepID)
require.NoError(t, err)
@@ -394,36 +408,37 @@ func TestKeeperDB_UpdateUpkeepLastKeeperIndex(t *testing.T) {
func TestKeeperDB_NewSetLastRunInfoForUpkeepOnJob(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, config, orm := setupKeeperDB(t)
ethKeyStore := cltest.NewKeyStore(t, db, config.Database()).Eth()
registry, j := cltest.MustInsertKeeperRegistry(t, db, orm, ethKeyStore, 0, 1, 20)
- upkeep := cltest.MustInsertUpkeepForRegistry(t, db, config.Database(), registry)
+ upkeep := cltest.MustInsertUpkeepForRegistry(t, db, registry)
registry.NumKeepers = 2
registry.KeeperIndexMap = map[types.EIP55Address]int32{
registry.FromAddress: 0,
types.EIP55AddressFromAddress(evmutils.ZeroAddress): 1,
}
- err := orm.UpsertRegistry(®istry)
+ err := orm.UpsertRegistry(ctx, ®istry)
require.NoError(t, err, "UPDATE keeper_registries")
// update
- rowsAffected, err := orm.SetLastRunInfoForUpkeepOnJob(j.ID, upkeep.UpkeepID, 100, registry.FromAddress)
+ rowsAffected, err := orm.SetLastRunInfoForUpkeepOnJob(ctx, j.ID, upkeep.UpkeepID, 100, registry.FromAddress)
require.NoError(t, err)
require.Equal(t, rowsAffected, int64(1))
assertLastRunHeight(t, db, upkeep, 100, 0)
// update to lower block height not allowed
- rowsAffected, err = orm.SetLastRunInfoForUpkeepOnJob(j.ID, upkeep.UpkeepID, 0, registry.FromAddress)
+ rowsAffected, err = orm.SetLastRunInfoForUpkeepOnJob(ctx, j.ID, upkeep.UpkeepID, 0, registry.FromAddress)
require.NoError(t, err)
require.Equal(t, rowsAffected, int64(0))
assertLastRunHeight(t, db, upkeep, 100, 0)
// update to same block height allowed
- rowsAffected, err = orm.SetLastRunInfoForUpkeepOnJob(j.ID, upkeep.UpkeepID, 100, types.EIP55AddressFromAddress(evmutils.ZeroAddress))
+ rowsAffected, err = orm.SetLastRunInfoForUpkeepOnJob(ctx, j.ID, upkeep.UpkeepID, 100, types.EIP55AddressFromAddress(evmutils.ZeroAddress))
require.NoError(t, err)
require.Equal(t, rowsAffected, int64(1))
assertLastRunHeight(t, db, upkeep, 100, 1)
// update to higher block height allowed
- rowsAffected, err = orm.SetLastRunInfoForUpkeepOnJob(j.ID, upkeep.UpkeepID, 101, registry.FromAddress)
+ rowsAffected, err = orm.SetLastRunInfoForUpkeepOnJob(ctx, j.ID, upkeep.UpkeepID, 101, registry.FromAddress)
require.NoError(t, err)
require.Equal(t, rowsAffected, int64(1))
assertLastRunHeight(t, db, upkeep, 101, 0)
diff --git a/core/services/keeper/registry1_1_synchronizer_test.go b/core/services/keeper/registry1_1_synchronizer_test.go
index e0c2ebb2b3a..61482208e5c 100644
--- a/core/services/keeper/registry1_1_synchronizer_test.go
+++ b/core/services/keeper/registry1_1_synchronizer_test.go
@@ -20,7 +20,6 @@ import (
registry1_1 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"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"
@@ -72,8 +71,7 @@ func mockRegistry1_1(
func Test_LogListenerOpts1_1(t *testing.T) {
db := pgtest.NewSqlxDB(t)
- scopedConfig := evmtest.NewChainScopedConfig(t, configtest.NewGeneralConfig(t, nil))
- korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
+ korm := keeper.NewORM(db, logger.TestLogger(t))
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address())
@@ -129,6 +127,7 @@ func Test_RegistrySynchronizer_CalcPositioningConstant(t *testing.T) {
}
func Test_RegistrySynchronizer1_1_FullSync(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, _, job := setupRegistrySync(t, keeper.RegistryVersion_1_1)
@@ -149,7 +148,7 @@ func Test_RegistrySynchronizer1_1_FullSync(t *testing.T) {
upkeepConfig,
2) // sync only 2 (#0,#2)
- synchronizer.ExportedFullSync()
+ synchronizer.ExportedFullSync(ctx)
cltest.AssertCount(t, db, "keeper_registries", 1)
cltest.AssertCount(t, db, "upkeep_registrations", 2)
@@ -194,7 +193,7 @@ func Test_RegistrySynchronizer1_1_FullSync(t *testing.T) {
big.NewInt(5),
upkeepConfig1_1,
2) // sync all 2 upkeeps (#2, #4)
- synchronizer.ExportedFullSync()
+ synchronizer.ExportedFullSync(ctx)
cltest.AssertCount(t, db, "keeper_registries", 1)
cltest.AssertCount(t, db, "upkeep_registrations", 2)
@@ -202,6 +201,7 @@ func Test_RegistrySynchronizer1_1_FullSync(t *testing.T) {
}
func Test_RegistrySynchronizer1_1_ConfigSetLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_1)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -236,11 +236,11 @@ func Test_RegistrySynchronizer1_1_ConfigSetLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.AssertRecordEventually(t, db, ®istry, fmt.Sprintf(`SELECT * FROM keeper_registries WHERE id = %d`, registry.ID), func() bool {
return registry.BlockCountPerTurn == 40
@@ -249,6 +249,7 @@ func Test_RegistrySynchronizer1_1_ConfigSetLog(t *testing.T) {
}
func Test_RegistrySynchronizer1_1_KeepersUpdatedLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_1)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -282,11 +283,11 @@ func Test_RegistrySynchronizer1_1_KeepersUpdatedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.AssertRecordEventually(t, db, ®istry, fmt.Sprintf(`SELECT * FROM keeper_registries WHERE id = %d`, registry.ID), func() bool {
return registry.NumKeepers == 2
@@ -294,6 +295,7 @@ func Test_RegistrySynchronizer1_1_KeepersUpdatedLog(t *testing.T) {
cltest.AssertCount(t, db, "keeper_registries", 1)
}
func Test_RegistrySynchronizer1_1_UpkeepCanceledLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_1)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -321,16 +323,17 @@ func Test_RegistrySynchronizer1_1_UpkeepCanceledLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_1_UpkeepRegisteredLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_1)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -361,16 +364,17 @@ func Test_RegistrySynchronizer1_1_UpkeepRegisteredLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_1_UpkeepPerformedLog(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_1)
@@ -402,11 +406,11 @@ func Test_RegistrySynchronizer1_1_UpkeepPerformedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
g.Eventually(func() int64 {
var upkeep keeper.UpkeepRegistration
diff --git a/core/services/keeper/registry1_2_synchronizer_test.go b/core/services/keeper/registry1_2_synchronizer_test.go
index 387452dddf9..a62e27b8759 100644
--- a/core/services/keeper/registry1_2_synchronizer_test.go
+++ b/core/services/keeper/registry1_2_synchronizer_test.go
@@ -19,7 +19,6 @@ import (
registry1_2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_2"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"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"
@@ -95,8 +94,7 @@ func mockRegistry1_2(
func Test_LogListenerOpts1_2(t *testing.T) {
db := pgtest.NewSqlxDB(t)
- scopedConfig := evmtest.NewChainScopedConfig(t, configtest.NewGeneralConfig(t, nil))
- korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
+ korm := keeper.NewORM(db, logger.TestLogger(t))
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address())
@@ -148,6 +146,7 @@ func Test_RegistrySynchronizer1_2_Start(t *testing.T) {
}
func Test_RegistrySynchronizer1_2_FullSync(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, _, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
@@ -167,7 +166,7 @@ func Test_RegistrySynchronizer1_2_FullSync(t *testing.T) {
3, // sync all 3
2,
1)
- synchronizer.ExportedFullSync()
+ synchronizer.ExportedFullSync(ctx)
cltest.AssertCount(t, db, "keeper_registries", 1)
cltest.AssertCount(t, db, "upkeep_registrations", 3)
@@ -213,7 +212,7 @@ func Test_RegistrySynchronizer1_2_FullSync(t *testing.T) {
3, // sync all 3 active upkeeps
2,
1)
- synchronizer.ExportedFullSync()
+ synchronizer.ExportedFullSync(ctx)
cltest.AssertCount(t, db, "keeper_registries", 1)
cltest.AssertCount(t, db, "upkeep_registrations", 3)
@@ -221,6 +220,7 @@ func Test_RegistrySynchronizer1_2_FullSync(t *testing.T) {
}
func Test_RegistrySynchronizer1_2_ConfigSetLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -259,11 +259,11 @@ func Test_RegistrySynchronizer1_2_ConfigSetLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.AssertRecordEventually(t, db, ®istry, fmt.Sprintf(`SELECT * FROM keeper_registries WHERE id = %d`, registry.ID), func() bool {
return registry.BlockCountPerTurn == 40
@@ -272,6 +272,7 @@ func Test_RegistrySynchronizer1_2_ConfigSetLog(t *testing.T) {
}
func Test_RegistrySynchronizer1_2_KeepersUpdatedLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -309,11 +310,11 @@ func Test_RegistrySynchronizer1_2_KeepersUpdatedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.AssertRecordEventually(t, db, ®istry, fmt.Sprintf(`SELECT * FROM keeper_registries WHERE id = %d`, registry.ID), func() bool {
return registry.NumKeepers == 2
@@ -322,6 +323,7 @@ func Test_RegistrySynchronizer1_2_KeepersUpdatedLog(t *testing.T) {
}
func Test_RegistrySynchronizer1_2_UpkeepCanceledLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -350,16 +352,17 @@ func Test_RegistrySynchronizer1_2_UpkeepCanceledLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_2_UpkeepRegisteredLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -391,16 +394,17 @@ func Test_RegistrySynchronizer1_2_UpkeepRegisteredLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_2_UpkeepPerformedLog(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
@@ -433,11 +437,11 @@ func Test_RegistrySynchronizer1_2_UpkeepPerformedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
g.Eventually(func() int64 {
var upkeep keeper.UpkeepRegistration
@@ -455,6 +459,7 @@ func Test_RegistrySynchronizer1_2_UpkeepPerformedLog(t *testing.T) {
}
func Test_RegistrySynchronizer1_2_UpkeepGasLimitSetLog(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
@@ -497,16 +502,17 @@ func Test_RegistrySynchronizer1_2_UpkeepGasLimitSetLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
g.Eventually(getExecuteGas, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.Equal(uint32(4_000_000)))
}
func Test_RegistrySynchronizer1_2_UpkeepReceivedLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -538,16 +544,17 @@ func Test_RegistrySynchronizer1_2_UpkeepReceivedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_2_UpkeepMigratedLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_2)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -576,11 +583,11 @@ func Test_RegistrySynchronizer1_2_UpkeepMigratedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
diff --git a/core/services/keeper/registry1_3_synchronizer_test.go b/core/services/keeper/registry1_3_synchronizer_test.go
index 6fc919775cc..7ebbbc25469 100644
--- a/core/services/keeper/registry1_3_synchronizer_test.go
+++ b/core/services/keeper/registry1_3_synchronizer_test.go
@@ -21,7 +21,6 @@ import (
registry1_3 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"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"
@@ -97,8 +96,7 @@ func mockRegistry1_3(
func Test_LogListenerOpts1_3(t *testing.T) {
db := pgtest.NewSqlxDB(t)
- scopedConfig := evmtest.NewChainScopedConfig(t, configtest.NewGeneralConfig(t, nil))
- korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
+ korm := keeper.NewORM(db, logger.TestLogger(t))
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address())
@@ -153,6 +151,7 @@ func Test_RegistrySynchronizer1_3_Start(t *testing.T) {
}
func Test_RegistrySynchronizer1_3_FullSync(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, _, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
@@ -172,7 +171,7 @@ func Test_RegistrySynchronizer1_3_FullSync(t *testing.T) {
3, // sync all 3
2,
1)
- synchronizer.ExportedFullSync()
+ synchronizer.ExportedFullSync(ctx)
cltest.AssertCount(t, db, "keeper_registries", 1)
cltest.AssertCount(t, db, "upkeep_registrations", 3)
@@ -218,7 +217,7 @@ func Test_RegistrySynchronizer1_3_FullSync(t *testing.T) {
3, // sync all 3 upkeeps
2,
1)
- synchronizer.ExportedFullSync()
+ synchronizer.ExportedFullSync(ctx)
cltest.AssertCount(t, db, "keeper_registries", 1)
cltest.AssertCount(t, db, "upkeep_registrations", 3)
@@ -226,6 +225,7 @@ func Test_RegistrySynchronizer1_3_FullSync(t *testing.T) {
}
func Test_RegistrySynchronizer1_3_ConfigSetLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -264,11 +264,11 @@ func Test_RegistrySynchronizer1_3_ConfigSetLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.AssertRecordEventually(t, db, ®istry, fmt.Sprintf(`SELECT * FROM keeper_registries WHERE id = %d`, registry.ID), func() bool {
return registry.BlockCountPerTurn == 40
@@ -277,6 +277,7 @@ func Test_RegistrySynchronizer1_3_ConfigSetLog(t *testing.T) {
}
func Test_RegistrySynchronizer1_3_KeepersUpdatedLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -314,11 +315,11 @@ func Test_RegistrySynchronizer1_3_KeepersUpdatedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.AssertRecordEventually(t, db, ®istry, fmt.Sprintf(`SELECT * FROM keeper_registries WHERE id = %d`, registry.ID), func() bool {
return registry.NumKeepers == 2
@@ -327,6 +328,7 @@ func Test_RegistrySynchronizer1_3_KeepersUpdatedLog(t *testing.T) {
}
func Test_RegistrySynchronizer1_3_UpkeepCanceledLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -355,16 +357,17 @@ func Test_RegistrySynchronizer1_3_UpkeepCanceledLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_3_UpkeepRegisteredLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -396,16 +399,17 @@ func Test_RegistrySynchronizer1_3_UpkeepRegisteredLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_3_UpkeepPerformedLog(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
@@ -438,11 +442,11 @@ func Test_RegistrySynchronizer1_3_UpkeepPerformedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
g.Eventually(func() int64 {
var upkeep keeper.UpkeepRegistration
@@ -460,6 +464,7 @@ func Test_RegistrySynchronizer1_3_UpkeepPerformedLog(t *testing.T) {
}
func Test_RegistrySynchronizer1_3_UpkeepGasLimitSetLog(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
@@ -502,16 +507,17 @@ func Test_RegistrySynchronizer1_3_UpkeepGasLimitSetLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
g.Eventually(getExecuteGas, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.Equal(uint32(4_000_000)))
}
func Test_RegistrySynchronizer1_3_UpkeepReceivedLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -543,16 +549,17 @@ func Test_RegistrySynchronizer1_3_UpkeepReceivedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_3_UpkeepMigratedLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -581,17 +588,18 @@ func Test_RegistrySynchronizer1_3_UpkeepMigratedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
// race condition: "wait for count"
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
}
func Test_RegistrySynchronizer1_3_UpkeepPausedLog_UpkeepUnpausedLog(t *testing.T) {
+ ctx := testutils.Context(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
contractAddress := job.KeeperSpec.ContractAddress.Address()
@@ -621,11 +629,11 @@ func Test_RegistrySynchronizer1_3_UpkeepPausedLog_UpkeepUnpausedLog(t *testing.T
logBroadcast.On("DecodedLog").Return(&log)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 2)
@@ -636,11 +644,11 @@ func Test_RegistrySynchronizer1_3_UpkeepPausedLog_UpkeepUnpausedLog(t *testing.T
logBroadcast.On("DecodedLog").Return(&unpausedlog)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
cltest.WaitForCount(t, db, "upkeep_registrations", 3)
var upkeep keeper.UpkeepRegistration
@@ -658,6 +666,7 @@ func Test_RegistrySynchronizer1_3_UpkeepPausedLog_UpkeepUnpausedLog(t *testing.T
}
func Test_RegistrySynchronizer1_3_UpkeepCheckDataUpdatedLog(t *testing.T) {
+ ctx := testutils.Context(t)
g := gomega.NewWithT(t)
db, synchronizer, ethMock, lb, job := setupRegistrySync(t, keeper.RegistryVersion_1_3)
@@ -695,11 +704,11 @@ func Test_RegistrySynchronizer1_3_UpkeepCheckDataUpdatedLog(t *testing.T) {
logBroadcast.On("DecodedLog").Return(&updatedLog)
logBroadcast.On("RawLog").Return(rawLog)
logBroadcast.On("String").Maybe().Return("")
- lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
// Do the thing
- synchronizer.HandleLog(logBroadcast)
+ synchronizer.HandleLog(ctx, logBroadcast)
g.Eventually(func() []byte {
var upkeep keeper.UpkeepRegistration
diff --git a/core/services/keeper/registry_synchronizer_core.go b/core/services/keeper/registry_synchronizer_core.go
index 86c79ac0007..a720fa8f13c 100644
--- a/core/services/keeper/registry_synchronizer_core.go
+++ b/core/services/keeper/registry_synchronizer_core.go
@@ -27,7 +27,7 @@ var (
type RegistrySynchronizerOptions struct {
Job job.Job
RegistryWrapper RegistryWrapper
- ORM ORM
+ ORM *ORM
JRM job.ORM
LogBroadcaster log.Broadcaster
MailMon *mailbox.Monitor
@@ -49,7 +49,7 @@ type RegistrySynchronizer struct {
mbLogs *mailbox.Mailbox[log.Broadcast]
minIncomingConfirmations uint32
effectiveKeeperAddress common.Address
- orm ORM
+ orm *ORM
logger logger.SugaredLogger
wgDone sync.WaitGroup
syncUpkeepQueueSize uint32 //Represents the max number of upkeeps that can be synced in parallel
@@ -117,14 +117,14 @@ func (rs *RegistrySynchronizer) run() {
ctx, cancel := rs.chStop.NewCtx()
defer cancel()
- rs.fullSync()
+ rs.fullSync(ctx)
for {
select {
case <-rs.chStop:
return
case <-syncTicker.Ticks():
- rs.fullSync()
+ rs.fullSync(ctx)
syncTicker.Reset(rs.interval)
case <-rs.mbLogs.Notify():
rs.processLogs(ctx)
diff --git a/core/services/keeper/registry_synchronizer_helper_test.go b/core/services/keeper/registry_synchronizer_helper_test.go
index 19ba2eedbbb..c97d3c0c92c 100644
--- a/core/services/keeper/registry_synchronizer_helper_test.go
+++ b/core/services/keeper/registry_synchronizer_helper_test.go
@@ -38,8 +38,7 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) (
) {
db := pgtest.NewSqlxDB(t)
cfg := configtest.NewGeneralConfig(t, nil)
- scopedConfig := evmtest.NewChainScopedConfig(t, cfg)
- korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
+ korm := keeper.NewORM(db, logger.TestLogger(t))
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
keyStore := cltest.NewKeyStore(t, db, cfg.Database())
lbMock := logmocks.NewBroadcaster(t)
@@ -47,7 +46,6 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) (
j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, LogBroadcaster: lbMock, GeneralConfig: cfg, KeyStore: keyStore.Eth()})
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- ch := evmtest.MustGetDefaultChain(t, legacyChains)
jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), legacyChains, db, keyStore, nil, nil)
contractAddress := j.KeeperSpec.ContractAddress.Address()
@@ -75,7 +73,7 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) (
mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t))
- orm := keeper.NewORM(db, logger.TestLogger(t), ch.Config().Database())
+ orm := keeper.NewORM(db, logger.TestLogger(t))
synchronizer := keeper.NewRegistrySynchronizer(keeper.RegistrySynchronizerOptions{
Job: j,
RegistryWrapper: *registryWrapper,
diff --git a/core/services/keeper/registry_synchronizer_log_listener.go b/core/services/keeper/registry_synchronizer_log_listener.go
index 099d01d27f6..93ff2e9e950 100644
--- a/core/services/keeper/registry_synchronizer_log_listener.go
+++ b/core/services/keeper/registry_synchronizer_log_listener.go
@@ -1,6 +1,7 @@
package keeper
import (
+ "context"
"reflect"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/log"
@@ -10,7 +11,7 @@ func (rs *RegistrySynchronizer) JobID() int32 {
return rs.job.ID
}
-func (rs *RegistrySynchronizer) HandleLog(broadcast log.Broadcast) {
+func (rs *RegistrySynchronizer) HandleLog(ctx context.Context, broadcast log.Broadcast) {
eventLog := broadcast.DecodedLog()
if eventLog == nil || reflect.ValueOf(eventLog).IsNil() {
rs.logger.Panicf("HandleLog: ignoring nil value, type: %T", broadcast)
diff --git a/core/services/keeper/registry_synchronizer_process_logs.go b/core/services/keeper/registry_synchronizer_process_logs.go
index 5dfdc7b6950..a1bdcd8db0b 100644
--- a/core/services/keeper/registry_synchronizer_process_logs.go
+++ b/core/services/keeper/registry_synchronizer_process_logs.go
@@ -38,43 +38,43 @@ func (rs *RegistrySynchronizer) processLogs(ctx context.Context) {
*registry1_2.KeeperRegistryConfigSet,
*registry1_3.KeeperRegistryKeepersUpdated,
*registry1_3.KeeperRegistryConfigSet:
- err = rs.handleSyncRegistryLog(broadcast)
+ err = rs.handleSyncRegistryLog(ctx, broadcast)
case *registry1_1.KeeperRegistryUpkeepCanceled,
*registry1_2.KeeperRegistryUpkeepCanceled,
*registry1_3.KeeperRegistryUpkeepCanceled:
- err = rs.handleUpkeepCancelled(broadcast)
+ err = rs.handleUpkeepCancelled(ctx, broadcast)
case *registry1_1.KeeperRegistryUpkeepRegistered,
*registry1_2.KeeperRegistryUpkeepRegistered,
*registry1_3.KeeperRegistryUpkeepRegistered:
- err = rs.handleUpkeepRegistered(broadcast)
+ err = rs.handleUpkeepRegistered(ctx, broadcast)
case *registry1_1.KeeperRegistryUpkeepPerformed,
*registry1_2.KeeperRegistryUpkeepPerformed,
*registry1_3.KeeperRegistryUpkeepPerformed:
- err = rs.handleUpkeepPerformed(broadcast)
+ err = rs.handleUpkeepPerformed(ctx, broadcast)
case *registry1_2.KeeperRegistryUpkeepGasLimitSet,
*registry1_3.KeeperRegistryUpkeepGasLimitSet:
- err = rs.handleUpkeepGasLimitSet(broadcast)
+ err = rs.handleUpkeepGasLimitSet(ctx, broadcast)
case *registry1_2.KeeperRegistryUpkeepReceived,
*registry1_3.KeeperRegistryUpkeepReceived:
- err = rs.handleUpkeepReceived(broadcast)
+ err = rs.handleUpkeepReceived(ctx, broadcast)
case *registry1_2.KeeperRegistryUpkeepMigrated,
*registry1_3.KeeperRegistryUpkeepMigrated:
- err = rs.handleUpkeepMigrated(broadcast)
+ err = rs.handleUpkeepMigrated(ctx, broadcast)
case *registry1_3.KeeperRegistryUpkeepPaused:
- err = rs.handleUpkeepPaused(broadcast)
+ err = rs.handleUpkeepPaused(ctx, broadcast)
case *registry1_3.KeeperRegistryUpkeepUnpaused:
- err = rs.handleUpkeepUnpaused(broadcast)
+ err = rs.handleUpkeepUnpaused(ctx, broadcast)
case *registry1_3.KeeperRegistryUpkeepCheckDataUpdated:
- err = rs.handleUpkeepCheckDataUpdated(broadcast)
+ err = rs.handleUpkeepCheckDataUpdated(ctx, broadcast)
default:
rs.logger.Warn("unexpected log type")
@@ -85,24 +85,24 @@ func (rs *RegistrySynchronizer) processLogs(ctx context.Context) {
rs.logger.Error(err)
}
- err = rs.logBroadcaster.MarkConsumed(ctx, broadcast)
+ err = rs.logBroadcaster.MarkConsumed(ctx, nil, broadcast)
if err != nil {
rs.logger.Error(errors.Wrapf(err, "unable to mark %T log as consumed, log: %v", broadcast.RawLog(), broadcast.String()))
}
}
}
-func (rs *RegistrySynchronizer) handleSyncRegistryLog(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleSyncRegistryLog(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing SyncRegistry log", "txHash", broadcast.RawLog().TxHash.Hex())
- _, err := rs.syncRegistry()
+ _, err := rs.syncRegistry(ctx)
if err != nil {
return errors.Wrap(err, "unable to sync registry")
}
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepCancelled(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepCancelled(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing UpkeepCanceled log", "txHash", broadcast.RawLog().TxHash.Hex())
cancelledID, err := rs.registryWrapper.GetCancelledUpkeepIDFromLog(broadcast)
@@ -110,7 +110,7 @@ func (rs *RegistrySynchronizer) handleUpkeepCancelled(broadcast log.Broadcast) e
return errors.Wrap(err, "Unable to fetch cancelled upkeep ID from log")
}
- affected, err := rs.orm.BatchDeleteUpkeepsForJob(rs.job.ID, []big.Big{*big.New(cancelledID)})
+ affected, err := rs.orm.BatchDeleteUpkeepsForJob(ctx, rs.job.ID, []big.Big{*big.New(cancelledID)})
if err != nil {
return errors.Wrap(err, "unable to batch delete upkeeps")
}
@@ -118,10 +118,10 @@ func (rs *RegistrySynchronizer) handleUpkeepCancelled(broadcast log.Broadcast) e
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepRegistered(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepRegistered(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing UpkeepRegistered log", "txHash", broadcast.RawLog().TxHash.Hex())
- registry, err := rs.orm.RegistryForJob(rs.job.ID)
+ registry, err := rs.orm.RegistryForJob(ctx, rs.job.ID)
if err != nil {
return errors.Wrap(err, "unable to find registry for job")
}
@@ -131,21 +131,21 @@ func (rs *RegistrySynchronizer) handleUpkeepRegistered(broadcast log.Broadcast)
return errors.Wrap(err, "Unable to fetch upkeep ID from registration log")
}
- err = rs.syncUpkeep(&rs.registryWrapper, registry, big.New(upkeepID))
+ err = rs.syncUpkeep(ctx, &rs.registryWrapper, registry, big.New(upkeepID))
if err != nil {
return errors.Wrapf(err, "failed to sync upkeep, log: %v", broadcast.String())
}
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepPerformed(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepPerformed(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing UpkeepPerformed log", "jobID", rs.job.ID, "txHash", broadcast.RawLog().TxHash.Hex())
log, err := rs.registryWrapper.ParseUpkeepPerformedLog(broadcast)
if err != nil {
return errors.Wrap(err, "Unable to fetch upkeep ID from performed log")
}
- rowsAffected, err := rs.orm.SetLastRunInfoForUpkeepOnJob(rs.job.ID, big.New(log.UpkeepID), int64(broadcast.RawLog().BlockNumber), types.EIP55AddressFromAddress(log.FromKeeper))
+ rowsAffected, err := rs.orm.SetLastRunInfoForUpkeepOnJob(ctx, rs.job.ID, big.New(log.UpkeepID), int64(broadcast.RawLog().BlockNumber), types.EIP55AddressFromAddress(log.FromKeeper))
if err != nil {
return errors.Wrap(err, "failed to set last run to 0")
}
@@ -159,10 +159,10 @@ func (rs *RegistrySynchronizer) handleUpkeepPerformed(broadcast log.Broadcast) e
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepGasLimitSet(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepGasLimitSet(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing UpkeepGasLimitSet log", "jobID", rs.job.ID, "txHash", broadcast.RawLog().TxHash.Hex())
- registry, err := rs.orm.RegistryForJob(rs.job.ID)
+ registry, err := rs.orm.RegistryForJob(ctx, rs.job.ID)
if err != nil {
return errors.Wrap(err, "unable to find registry for job")
}
@@ -172,17 +172,17 @@ func (rs *RegistrySynchronizer) handleUpkeepGasLimitSet(broadcast log.Broadcast)
return errors.Wrap(err, "Unable to fetch upkeep ID from gas limit set log")
}
- err = rs.syncUpkeep(&rs.registryWrapper, registry, big.New(upkeepID))
+ err = rs.syncUpkeep(ctx, &rs.registryWrapper, registry, big.New(upkeepID))
if err != nil {
return errors.Wrapf(err, "failed to sync upkeep, log: %v", broadcast.String())
}
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepReceived(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepReceived(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing UpkeepReceived log", "txHash", broadcast.RawLog().TxHash.Hex())
- registry, err := rs.orm.RegistryForJob(rs.job.ID)
+ registry, err := rs.orm.RegistryForJob(ctx, rs.job.ID)
if err != nil {
return errors.Wrap(err, "unable to find registry for job")
}
@@ -192,14 +192,14 @@ func (rs *RegistrySynchronizer) handleUpkeepReceived(broadcast log.Broadcast) er
return errors.Wrap(err, "Unable to fetch upkeep ID from received log")
}
- err = rs.syncUpkeep(&rs.registryWrapper, registry, big.New(upkeepID))
+ err = rs.syncUpkeep(ctx, &rs.registryWrapper, registry, big.New(upkeepID))
if err != nil {
return errors.Wrapf(err, "failed to sync upkeep, log: %v", broadcast.String())
}
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepMigrated(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepMigrated(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing UpkeepMigrated log", "txHash", broadcast.RawLog().TxHash.Hex())
migratedID, err := rs.registryWrapper.GetUpkeepIdFromMigratedLog(broadcast)
@@ -207,7 +207,7 @@ func (rs *RegistrySynchronizer) handleUpkeepMigrated(broadcast log.Broadcast) er
return errors.Wrap(err, "Unable to fetch migrated upkeep ID from log")
}
- affected, err := rs.orm.BatchDeleteUpkeepsForJob(rs.job.ID, []big.Big{*big.New(migratedID)})
+ affected, err := rs.orm.BatchDeleteUpkeepsForJob(ctx, rs.job.ID, []big.Big{*big.New(migratedID)})
if err != nil {
return errors.Wrap(err, "unable to batch delete upkeeps")
}
@@ -215,7 +215,7 @@ func (rs *RegistrySynchronizer) handleUpkeepMigrated(broadcast log.Broadcast) er
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepPaused(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepPaused(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing UpkeepPaused log", "txHash", broadcast.RawLog().TxHash.Hex())
pausedUpkeepId, err := rs.registryWrapper.GetUpkeepIdFromUpkeepPausedLog(broadcast)
@@ -223,7 +223,7 @@ func (rs *RegistrySynchronizer) handleUpkeepPaused(broadcast log.Broadcast) erro
return errors.Wrap(err, "Unable to fetch upkeep ID from upkeep paused log")
}
- _, err = rs.orm.BatchDeleteUpkeepsForJob(rs.job.ID, []big.Big{*big.New(pausedUpkeepId)})
+ _, err = rs.orm.BatchDeleteUpkeepsForJob(ctx, rs.job.ID, []big.Big{*big.New(pausedUpkeepId)})
if err != nil {
return errors.Wrap(err, "unable to batch delete upkeeps")
}
@@ -231,10 +231,10 @@ func (rs *RegistrySynchronizer) handleUpkeepPaused(broadcast log.Broadcast) erro
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepUnpaused(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepUnpaused(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing UpkeepUnpaused log", "txHash", broadcast.RawLog().TxHash.Hex())
- registry, err := rs.orm.RegistryForJob(rs.job.ID)
+ registry, err := rs.orm.RegistryForJob(ctx, rs.job.ID)
if err != nil {
return errors.Wrap(err, "unable to find registry for job")
}
@@ -244,7 +244,7 @@ func (rs *RegistrySynchronizer) handleUpkeepUnpaused(broadcast log.Broadcast) er
return errors.Wrap(err, "Unable to fetch upkeep ID from upkeep unpaused log")
}
- err = rs.syncUpkeep(&rs.registryWrapper, registry, big.New(unpausedUpkeepId))
+ err = rs.syncUpkeep(ctx, &rs.registryWrapper, registry, big.New(unpausedUpkeepId))
if err != nil {
return errors.Wrapf(err, "failed to sync upkeep, log: %s", broadcast.String())
}
@@ -252,10 +252,10 @@ func (rs *RegistrySynchronizer) handleUpkeepUnpaused(broadcast log.Broadcast) er
return nil
}
-func (rs *RegistrySynchronizer) handleUpkeepCheckDataUpdated(broadcast log.Broadcast) error {
+func (rs *RegistrySynchronizer) handleUpkeepCheckDataUpdated(ctx context.Context, broadcast log.Broadcast) error {
rs.logger.Debugw("processing Upkeep check data updated log", "txHash", broadcast.RawLog().TxHash.Hex())
- registry, err := rs.orm.RegistryForJob(rs.job.ID)
+ registry, err := rs.orm.RegistryForJob(ctx, rs.job.ID)
if err != nil {
return errors.Wrap(err, "unable to find registry for job")
}
@@ -265,7 +265,7 @@ func (rs *RegistrySynchronizer) handleUpkeepCheckDataUpdated(broadcast log.Broad
return errors.Wrap(err, "Unable to parse update log from upkeep check data updated log")
}
- err = rs.syncUpkeep(&rs.registryWrapper, registry, big.New(updateLog.UpkeepID))
+ err = rs.syncUpkeep(ctx, &rs.registryWrapper, registry, big.New(updateLog.UpkeepID))
if err != nil {
return errors.Wrapf(err, "unable to update check data for upkeep %s", updateLog.UpkeepID.String())
}
diff --git a/core/services/keeper/registry_synchronizer_sync.go b/core/services/keeper/registry_synchronizer_sync.go
index cdca9512976..6c0e12d844b 100644
--- a/core/services/keeper/registry_synchronizer_sync.go
+++ b/core/services/keeper/registry_synchronizer_sync.go
@@ -1,6 +1,7 @@
package keeper
import (
+ "context"
"encoding/binary"
"math"
"sync"
@@ -12,29 +13,29 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
)
-func (rs *RegistrySynchronizer) fullSync() {
+func (rs *RegistrySynchronizer) fullSync(ctx context.Context) {
rs.logger.Debugf("fullSyncing registry %s", rs.job.KeeperSpec.ContractAddress.Hex())
- registry, err := rs.syncRegistry()
+ registry, err := rs.syncRegistry(ctx)
if err != nil {
rs.logger.Error(errors.Wrap(err, "failed to sync registry during fullSyncing registry"))
return
}
- if err := rs.fullSyncUpkeeps(registry); err != nil {
+ if err := rs.fullSyncUpkeeps(ctx, registry); err != nil {
rs.logger.Error(errors.Wrap(err, "failed to sync upkeeps during fullSyncing registry"))
return
}
rs.logger.Debugf("fullSyncing registry successful %s", rs.job.KeeperSpec.ContractAddress.Hex())
}
-func (rs *RegistrySynchronizer) syncRegistry() (Registry, error) {
+func (rs *RegistrySynchronizer) syncRegistry(ctx context.Context) (Registry, error) {
registry, err := rs.newRegistryFromChain()
if err != nil {
return Registry{}, errors.Wrap(err, "failed to get new registry from chain")
}
- err = rs.orm.UpsertRegistry(®istry)
+ err = rs.orm.UpsertRegistry(ctx, ®istry)
if err != nil {
return Registry{}, errors.Wrap(err, "failed to upsert registry")
}
@@ -42,13 +43,13 @@ func (rs *RegistrySynchronizer) syncRegistry() (Registry, error) {
return registry, nil
}
-func (rs *RegistrySynchronizer) fullSyncUpkeeps(reg Registry) error {
+func (rs *RegistrySynchronizer) fullSyncUpkeeps(ctx context.Context, reg Registry) error {
activeUpkeepIDs, err := rs.registryWrapper.GetActiveUpkeepIDs(nil)
if err != nil {
return errors.Wrap(err, "unable to get active upkeep IDs")
}
- existingUpkeepIDs, err := rs.orm.AllUpkeepIDsForRegistry(reg.ID)
+ existingUpkeepIDs, err := rs.orm.AllUpkeepIDsForRegistry(ctx, reg.ID)
if err != nil {
return errors.Wrap(err, "unable to fetch existing upkeep IDs from DB")
}
@@ -59,7 +60,7 @@ func (rs *RegistrySynchronizer) fullSyncUpkeeps(reg Registry) error {
activeSet[upkeepID.String()] = true
allActiveUpkeeps = append(allActiveUpkeeps, *big.New(upkeepID))
}
- rs.batchSyncUpkeepsOnRegistry(reg, allActiveUpkeeps)
+ rs.batchSyncUpkeepsOnRegistry(ctx, reg, allActiveUpkeeps)
// All upkeeps in existingUpkeepIDs, not in activeUpkeepIDs should be deleted
canceled := make([]big.Big, 0)
@@ -68,7 +69,7 @@ func (rs *RegistrySynchronizer) fullSyncUpkeeps(reg Registry) error {
canceled = append(canceled, upkeepID)
}
}
- if _, err := rs.orm.BatchDeleteUpkeepsForJob(rs.job.ID, canceled); err != nil {
+ if _, err := rs.orm.BatchDeleteUpkeepsForJob(ctx, rs.job.ID, canceled); err != nil {
return errors.Wrap(err, "failed to batch delete upkeeps from job")
}
return nil
@@ -76,28 +77,27 @@ func (rs *RegistrySynchronizer) fullSyncUpkeeps(reg Registry) error {
// batchSyncUpkeepsOnRegistry syncs upkeeps at a time in parallel
// for all the IDs within newUpkeeps slice
-func (rs *RegistrySynchronizer) batchSyncUpkeepsOnRegistry(reg Registry, newUpkeeps []big.Big) {
+func (rs *RegistrySynchronizer) batchSyncUpkeepsOnRegistry(ctx context.Context, reg Registry, newUpkeeps []big.Big) {
wg := sync.WaitGroup{}
- wg.Add(len(newUpkeeps))
chSyncUpkeepQueue := make(chan struct{}, rs.syncUpkeepQueueSize)
done := func() { <-chSyncUpkeepQueue; wg.Done() }
for i := range newUpkeeps {
select {
- case <-rs.chStop:
- return
+ case <-ctx.Done():
case chSyncUpkeepQueue <- struct{}{}:
- go rs.syncUpkeepWithCallback(&rs.registryWrapper, reg, &newUpkeeps[i], done)
+ wg.Add(1)
+ go rs.syncUpkeepWithCallback(ctx, &rs.registryWrapper, reg, &newUpkeeps[i], done)
}
}
wg.Wait()
}
-func (rs *RegistrySynchronizer) syncUpkeepWithCallback(getter upkeepGetter, registry Registry, upkeepID *big.Big, doneCallback func()) {
+func (rs *RegistrySynchronizer) syncUpkeepWithCallback(ctx context.Context, getter upkeepGetter, registry Registry, upkeepID *big.Big, doneCallback func()) {
defer doneCallback()
- if err := rs.syncUpkeep(getter, registry, upkeepID); err != nil {
+ if err := rs.syncUpkeep(ctx, getter, registry, upkeepID); err != nil {
rs.logger.With("err", err.Error()).With(
"upkeepID", NewUpkeepIdentifier(upkeepID).String(),
"registryContract", registry.ContractAddress.Hex(),
@@ -105,7 +105,7 @@ func (rs *RegistrySynchronizer) syncUpkeepWithCallback(getter upkeepGetter, regi
}
}
-func (rs *RegistrySynchronizer) syncUpkeep(getter upkeepGetter, registry Registry, upkeepID *big.Big) error {
+func (rs *RegistrySynchronizer) syncUpkeep(ctx context.Context, getter upkeepGetter, registry Registry, upkeepID *big.Big) error {
upkeep, err := getter.GetUpkeep(nil, upkeepID.ToInt())
if err != nil {
return errors.Wrap(err, "failed to get upkeep config")
@@ -126,11 +126,11 @@ func (rs *RegistrySynchronizer) syncUpkeep(getter upkeepGetter, registry Registr
PositioningConstant: positioningConstant,
UpkeepID: upkeepID,
}
- if err := rs.orm.UpsertUpkeep(&newUpkeep); err != nil {
+ if err := rs.orm.UpsertUpkeep(ctx, &newUpkeep); err != nil {
return errors.Wrap(err, "failed to upsert upkeep")
}
- if err := rs.orm.UpdateUpkeepLastKeeperIndex(rs.job.ID, upkeepID, types.EIP55AddressFromAddress(upkeep.LastKeeper)); err != nil {
+ if err := rs.orm.UpdateUpkeepLastKeeperIndex(ctx, rs.job.ID, upkeepID, types.EIP55AddressFromAddress(upkeep.LastKeeper)); err != nil {
return errors.Wrap(err, "failed to update upkeep last keeper index")
}
diff --git a/core/services/keeper/registry_synchronizer_sync_test.go b/core/services/keeper/registry_synchronizer_sync_test.go
index e4d8e44e20a..7cc1c5a11cc 100644
--- a/core/services/keeper/registry_synchronizer_sync_test.go
+++ b/core/services/keeper/registry_synchronizer_sync_test.go
@@ -27,6 +27,7 @@ func (g *GetUpkeepFailure) GetUpkeep(opts *bind.CallOpts, id *big.Int) (*UpkeepC
}
func TestSyncUpkeepWithCallback_UpkeepNotFound(t *testing.T) {
+ ctx := testutils.Context(t)
log, logObserver := logger.TestLoggerObserved(t, zapcore.ErrorLevel)
synchronizer := &RegistrySynchronizer{
logger: log.(logger.SugaredLogger),
@@ -49,7 +50,7 @@ func TestSyncUpkeepWithCallback_UpkeepNotFound(t *testing.T) {
}
getter := &GetUpkeepFailure{}
- synchronizer.syncUpkeepWithCallback(getter, registry, id, doneFunc)
+ synchronizer.syncUpkeepWithCallback(ctx, getter, registry, id, doneFunc)
// logs should have the upkeep identifier included in the error context properly formatted
require.Equal(t, 1, logObserver.Len())
diff --git a/core/services/keeper/upkeep_executer.go b/core/services/keeper/upkeep_executer.go
index bab2f73edfc..c66f2d31c5a 100644
--- a/core/services/keeper/upkeep_executer.go
+++ b/core/services/keeper/upkeep_executer.go
@@ -23,7 +23,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
)
@@ -60,11 +59,11 @@ type UpkeepExecuter struct {
ethClient evmclient.Client
config UpkeepExecuterConfig
executionQueue chan struct{}
- headBroadcaster httypes.HeadBroadcasterRegistry
+ headBroadcaster httypes.HeadBroadcaster
gasEstimator gas.EvmFeeEstimator
job job.Job
mailbox *mailbox.Mailbox[*evmtypes.Head]
- orm ORM
+ orm *ORM
pr pipeline.Runner
logger logger.Logger
wgDone sync.WaitGroup
@@ -74,7 +73,7 @@ type UpkeepExecuter struct {
// NewUpkeepExecuter is the constructor of UpkeepExecuter
func NewUpkeepExecuter(
job job.Job,
- orm ORM,
+ orm *ORM,
pr pipeline.Runner,
ethClient evmclient.Client,
headBroadcaster httypes.HeadBroadcaster,
@@ -133,17 +132,19 @@ func (ex *UpkeepExecuter) OnNewLongestChain(_ context.Context, head *evmtypes.He
func (ex *UpkeepExecuter) run() {
defer ex.wgDone.Done()
+ ctx, cancel := ex.chStop.NewCtx()
+ defer cancel()
for {
select {
case <-ex.chStop:
return
case <-ex.mailbox.Notify():
- ex.processActiveUpkeeps()
+ ex.processActiveUpkeeps(ctx)
}
}
}
-func (ex *UpkeepExecuter) processActiveUpkeeps() {
+func (ex *UpkeepExecuter) processActiveUpkeeps(ctx context.Context) {
// Keepers could miss their turn in the turn taking algo if they are too overloaded
// with work because processActiveUpkeeps() blocks
head, exists := ex.mailbox.Retrieve()
@@ -154,7 +155,7 @@ func (ex *UpkeepExecuter) processActiveUpkeeps() {
ex.logger.Debugw("checking active upkeeps", "blockheight", head.Number)
- registry, err := ex.orm.RegistryByContractAddress(ex.job.KeeperSpec.ContractAddress)
+ registry, err := ex.orm.RegistryByContractAddress(ctx, ex.job.KeeperSpec.ContractAddress)
if err != nil {
ex.logger.Error(errors.Wrap(err, "unable to load registry"))
return
@@ -167,6 +168,7 @@ func (ex *UpkeepExecuter) processActiveUpkeeps() {
return
}
activeUpkeeps, err2 = ex.orm.EligibleUpkeepsForRegistry(
+ ctx,
ex.job.KeeperSpec.ContractAddress,
head.Number,
ex.config.MaxGracePeriod(),
@@ -232,7 +234,7 @@ func (ex *UpkeepExecuter) execute(upkeep UpkeepRegistration, head *evmtypes.Head
// Only after task runs where a tx was broadcast
if run.State == pipeline.RunStatusCompleted {
- rowsAffected, err := ex.orm.SetLastRunInfoForUpkeepOnJob(ex.job.ID, upkeep.UpkeepID, head.Number, upkeep.Registry.FromAddress, pg.WithParentCtx(ctxService))
+ rowsAffected, err := ex.orm.SetLastRunInfoForUpkeepOnJob(ctxService, ex.job.ID, upkeep.UpkeepID, head.Number, upkeep.Registry.FromAddress)
if err != nil {
svcLogger.Error(errors.Wrap(err, "failed to set last run height for upkeep"))
}
diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go
index fbe61f35743..10995ec3c0d 100644
--- a/core/services/keeper/upkeep_executer_test.go
+++ b/core/services/keeper/upkeep_executer_test.go
@@ -66,7 +66,7 @@ func setup(t *testing.T, estimator gas.EvmFeeEstimator, overrideFn func(c *chain
*txmmocks.MockEvmTxManager,
keystore.Master,
legacyevm.Chain,
- keeper.ORM,
+ *keeper.ORM,
) {
cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.Keeper.TurnLookBack = ptr[int64](0)
@@ -85,12 +85,12 @@ func setup(t *testing.T, estimator gas.EvmFeeEstimator, overrideFn func(c *chain
legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), legacyChains, db, keyStore, nil, nil)
ch := evmtest.MustGetDefaultChain(t, legacyChains)
- orm := keeper.NewORM(db, logger.TestLogger(t), ch.Config().Database())
+ orm := keeper.NewORM(db, logger.TestLogger(t))
registry, jb := cltest.MustInsertKeeperRegistry(t, db, orm, keyStore.Eth(), 0, 1, 20)
lggr := logger.TestLogger(t)
executer := keeper.NewUpkeepExecuter(jb, orm, jpv2.Pr, ethClient, ch.HeadBroadcaster(), ch.GasEstimator(), lggr, ch.Config().Keeper(), jb.KeeperSpec.FromAddress.Address())
- upkeep := cltest.MustInsertUpkeepForRegistry(t, db, ch.Config().Database(), registry)
+ upkeep := cltest.MustInsertUpkeepForRegistry(t, db, registry)
servicetest.Run(t, executer)
return db, cfg, ethClient, executer, registry, upkeep, jb, jpv2, txm, keyStore, ch, orm
}
@@ -267,7 +267,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) {
registry, jb := cltest.MustInsertKeeperRegistry(t, db, orm, keyStore.Eth(), 0, 1, 20)
// change chain ID to non-configured chain
jb.KeeperSpec.EVMChainID = (*ubig.Big)(big.NewInt(999))
- cltest.MustInsertUpkeepForRegistry(t, db, ch.Config().Database(), registry)
+ cltest.MustInsertUpkeepForRegistry(t, db, registry)
lggr := logger.TestLogger(t)
executer := keeper.NewUpkeepExecuter(jb, orm, jpv2.Pr, ethMock, ch.HeadBroadcaster(), ch.GasEstimator(), lggr, ch.Config().Keeper(), jb.KeeperSpec.FromAddress.Address())
err := executer.Start(testutils.Context(t))
diff --git a/core/services/llo/orm.go b/core/services/llo/orm.go
index e046d62ad89..6b14e543268 100644
--- a/core/services/llo/orm.go
+++ b/core/services/llo/orm.go
@@ -10,9 +10,8 @@ import (
"github.com/ethereum/go-ethereum/common"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo"
-
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
type ORM interface {
@@ -22,12 +21,12 @@ type ORM interface {
var _ ORM = &orm{}
type orm struct {
- q pg.Queryer
+ ds sqlutil.DataSource
evmChainID *big.Int
}
-func NewORM(q pg.Queryer, evmChainID *big.Int) ORM {
- return &orm{q, evmChainID}
+func NewORM(ds sqlutil.DataSource, evmChainID *big.Int) ORM {
+ return &orm{ds, evmChainID}
}
func (o *orm) LoadChannelDefinitions(ctx context.Context, addr common.Address) (dfns llotypes.ChannelDefinitions, blockNum int64, err error) {
@@ -36,7 +35,7 @@ func (o *orm) LoadChannelDefinitions(ctx context.Context, addr common.Address) (
BlockNum int64 `db:"block_num"`
}
var scanned scd
- err = o.q.GetContext(ctx, &scanned, "SELECT definitions, block_num FROM channel_definitions WHERE evm_chain_id = $1 AND addr = $2", o.evmChainID.String(), addr)
+ err = o.ds.GetContext(ctx, &scanned, "SELECT definitions, block_num FROM channel_definitions WHERE evm_chain_id = $1 AND addr = $2", o.evmChainID.String(), addr)
if errors.Is(err, sql.ErrNoRows) {
return dfns, blockNum, nil
} else if err != nil {
@@ -53,7 +52,7 @@ func (o *orm) LoadChannelDefinitions(ctx context.Context, addr common.Address) (
// TODO: Test this method
// https://smartcontract-it.atlassian.net/jira/software/c/projects/MERC/issues/MERC-3653
func (o *orm) StoreChannelDefinitions(ctx context.Context, addr common.Address, dfns llotypes.ChannelDefinitions, blockNum int64) error {
- _, err := o.q.ExecContext(ctx, `
+ _, err := o.ds.ExecContext(ctx, `
INSERT INTO channel_definitions (evm_chain_id, addr, definitions, block_num, updated_at)
VALUES ($1, $2, $3, $4, NOW())
ON CONFLICT (evm_chain_id, addr) DO UPDATE
diff --git a/core/services/ocr/contract_tracker.go b/core/services/ocr/contract_tracker.go
index e4845ee3bc2..5746f97cd38 100644
--- a/core/services/ocr/contract_tracker.go
+++ b/core/services/ocr/contract_tracker.go
@@ -14,13 +14,12 @@ import (
gethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
- "github.com/jmoiron/sqlx"
-
"github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator"
"github.com/smartcontractkit/libocr/offchainreporting/confighelper"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting/types"
"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/common/config"
@@ -31,7 +30,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/offchain_aggregator_wrapper"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
// configMailboxSanityLimit is the maximum number of configs that can be held
@@ -64,7 +62,7 @@ type (
jobID int32
logger logger.Logger
ocrDB OCRContractTrackerDB
- q pg.Q
+ ds sqlutil.DataSource
blockTranslator ocrcommon.BlockTranslator
cfg ocrcommon.Config
mailMon *mailbox.Monitor
@@ -92,8 +90,8 @@ type (
}
OCRContractTrackerDB interface {
- SaveLatestRoundRequested(tx pg.Queryer, rr offchainaggregator.OffchainAggregatorRoundRequested) error
- LoadLatestRoundRequested() (rr offchainaggregator.OffchainAggregatorRoundRequested, err error)
+ SaveLatestRoundRequested(ctx context.Context, tx sqlutil.DataSource, rr offchainaggregator.OffchainAggregatorRoundRequested) error
+ LoadLatestRoundRequested(ctx context.Context) (rr offchainaggregator.OffchainAggregatorRoundRequested, err error)
}
)
@@ -112,10 +110,9 @@ func NewOCRContractTracker(
logBroadcaster log.Broadcaster,
jobID int32,
logger logger.Logger,
- db *sqlx.DB,
+ ds sqlutil.DataSource,
ocrDB OCRContractTrackerDB,
cfg ocrcommon.Config,
- q pg.QConfig,
headBroadcaster httypes.HeadBroadcaster,
mailMon *mailbox.Monitor,
) (o *OCRContractTracker) {
@@ -129,7 +126,7 @@ func NewOCRContractTracker(
jobID: jobID,
logger: logger,
ocrDB: ocrDB,
- q: pg.NewQ(db, logger, q),
+ ds: ds,
blockTranslator: ocrcommon.NewBlockTranslator(cfg, ethClient, logger),
cfg: cfg,
mailMon: mailMon,
@@ -144,9 +141,9 @@ func NewOCRContractTracker(
// Start must be called before logs can be delivered
// It ought to be called before starting OCR
-func (t *OCRContractTracker) Start(context.Context) error {
+func (t *OCRContractTracker) Start(ctx context.Context) error {
return t.StartOnce("OCRContractTracker", func() (err error) {
- t.latestRoundRequested, err = t.ocrDB.LoadLatestRoundRequested()
+ t.latestRoundRequested, err = t.ocrDB.LoadLatestRoundRequested(ctx)
if err != nil {
return errors.Wrap(err, "OCRContractTracker#Start: failed to load latest round requested")
}
@@ -240,10 +237,7 @@ func (t *OCRContractTracker) processLogs() {
// HandleLog complies with LogListener interface
// It is not thread safe
-func (t *OCRContractTracker) HandleLog(lb log.Broadcast) {
- ctx, cancel := t.chStop.NewCtx()
- defer cancel()
-
+func (t *OCRContractTracker) HandleLog(ctx context.Context, lb log.Broadcast) {
was, err := t.logBroadcaster.WasAlreadyConsumed(ctx, lb)
if err != nil {
t.logger.Errorw("could not determine if log was already consumed", "err", err)
@@ -255,14 +249,14 @@ func (t *OCRContractTracker) HandleLog(lb log.Broadcast) {
raw := lb.RawLog()
if raw.Address != t.contract.Address() {
t.logger.Errorf("log address of 0x%x does not match configured contract address of 0x%x", raw.Address, t.contract.Address())
- if err2 := t.logBroadcaster.MarkConsumed(ctx, lb); err2 != nil {
+ if err2 := t.logBroadcaster.MarkConsumed(ctx, nil, lb); err2 != nil {
t.logger.Errorw("failed to mark log consumed", "err", err2)
}
return
}
topics := raw.Topics
if len(topics) == 0 {
- if err2 := t.logBroadcaster.MarkConsumed(ctx, lb); err2 != nil {
+ if err2 := t.logBroadcaster.MarkConsumed(ctx, nil, lb); err2 != nil {
t.logger.Errorw("failed to mark log consumed", "err", err2)
}
return
@@ -275,7 +269,7 @@ func (t *OCRContractTracker) HandleLog(lb log.Broadcast) {
configSet, err = t.contractFilterer.ParseConfigSet(raw)
if err != nil {
t.logger.Errorw("could not parse config set", "err", err)
- if err2 := t.logBroadcaster.MarkConsumed(ctx, lb); err2 != nil {
+ if err2 := t.logBroadcaster.MarkConsumed(ctx, nil, lb); err2 != nil {
t.logger.Errorw("failed to mark log consumed", "err", err2)
}
return
@@ -292,17 +286,17 @@ func (t *OCRContractTracker) HandleLog(lb log.Broadcast) {
rr, err = t.contractFilterer.ParseRoundRequested(raw)
if err != nil {
t.logger.Errorw("could not parse round requested", "err", err)
- if err2 := t.logBroadcaster.MarkConsumed(ctx, lb); err2 != nil {
+ if err2 := t.logBroadcaster.MarkConsumed(ctx, nil, lb); err2 != nil {
t.logger.Errorw("failed to mark log consumed", "err", err2)
}
return
}
if IsLaterThan(raw, t.latestRoundRequested.Raw) {
- err = t.q.Transaction(func(tx pg.Queryer) error {
- if err = t.ocrDB.SaveLatestRoundRequested(tx, *rr); err != nil {
+ err = sqlutil.TransactDataSource(ctx, t.ds, nil, func(tx sqlutil.DataSource) error {
+ if err = t.ocrDB.SaveLatestRoundRequested(ctx, tx, *rr); err != nil {
return err
}
- return t.logBroadcaster.MarkConsumed(ctx, lb)
+ return t.logBroadcaster.MarkConsumed(ctx, tx, lb)
})
if err != nil {
t.logger.Error(err)
@@ -320,7 +314,7 @@ func (t *OCRContractTracker) HandleLog(lb log.Broadcast) {
t.logger.Debugw("got unrecognised log topic", "topic", topics[0])
}
if !consumed {
- if err := t.logBroadcaster.MarkConsumed(ctx, lb); err != nil {
+ if err := t.logBroadcaster.MarkConsumed(ctx, nil, lb); err != nil {
t.logger.Errorw("failed to mark log consumed", "err", err)
}
}
diff --git a/core/services/ocr/contract_tracker_test.go b/core/services/ocr/contract_tracker_test.go
index 185a9cd3197..5473a2c924c 100644
--- a/core/services/ocr/contract_tracker_test.go
+++ b/core/services/ocr/contract_tracker_test.go
@@ -18,7 +18,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox/mailboxtest"
- commonmocks "github.com/smartcontractkit/chainlink/v2/common/mocks"
+ htmocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks"
evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
logmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks"
@@ -49,7 +49,7 @@ func mustNewFilterer(t *testing.T) *offchainaggregator.OffchainAggregatorFiltere
type contractTrackerUni struct {
db *ocrmocks.OCRContractTrackerDB
lb *logmocks.Broadcaster
- hb *commonmocks.HeadBroadcaster[*evmtypes.Head, common.Hash]
+ hb *htmocks.HeadBroadcaster[*evmtypes.Head, common.Hash]
ec *evmclimocks.Client
tracker *ocr.OCRContractTracker
}
@@ -81,7 +81,7 @@ func newContractTrackerUni(t *testing.T, opts ...interface{}) (uni contractTrack
}
uni.db = ocrmocks.NewOCRContractTrackerDB(t)
uni.lb = logmocks.NewBroadcaster(t)
- uni.hb = commonmocks.NewHeadBroadcaster[*evmtypes.Head, common.Hash](t)
+ uni.hb = htmocks.NewHeadBroadcaster[*evmtypes.Head, common.Hash](t)
uni.ec = evmtest.NewEthClientMock(t)
mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t))
@@ -97,7 +97,6 @@ func newContractTrackerUni(t *testing.T, opts ...interface{}) (uni contractTrack
db,
uni.db,
cfg.EVM(),
- cfg.Database(),
uni.hb,
mailMon,
)
@@ -146,7 +145,7 @@ func Test_OCRContractTracker_LatestBlockHeight(t *testing.T) {
uni := newContractTrackerUni(t)
uni.hb.On("Subscribe", uni.tracker).Return(&evmtypes.Head{Number: 42}, func() {})
- uni.db.On("LoadLatestRoundRequested").Return(offchainaggregator.OffchainAggregatorRoundRequested{}, nil)
+ uni.db.On("LoadLatestRoundRequested", mock.Anything).Return(offchainaggregator.OffchainAggregatorRoundRequested{}, nil)
uni.lb.On("Register", uni.tracker, mock.Anything).Return(func() {})
servicetest.Run(t, uni.tracker)
@@ -172,7 +171,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
rawLog := cltest.LogFromFixture(t, "../../testdata/jsonrpc/round_requested_log_1_1.json")
logBroadcast.On("RawLog").Return(rawLog).Maybe()
logBroadcast.On("String").Return("").Maybe()
- uni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
configDigest, epoch, round, err := uni.tracker.LatestRoundRequested(testutils.Context(t), 0)
@@ -181,7 +180,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
require.Equal(t, 0, int(round))
require.Equal(t, 0, int(epoch))
- uni.tracker.HandleLog(logBroadcast)
+ uni.tracker.HandleLog(testutils.Context(t), logBroadcast)
configDigest, epoch, round, err = uni.tracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -203,7 +202,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
require.Equal(t, 0, int(round))
require.Equal(t, 0, int(epoch))
- uni.tracker.HandleLog(logBroadcast)
+ uni.tracker.HandleLog(testutils.Context(t), logBroadcast)
configDigest, epoch, round, err = uni.tracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -228,13 +227,13 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
logBroadcast.On("RawLog").Return(rawLog).Maybe()
logBroadcast.On("String").Return("").Maybe()
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- uni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
- uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool {
+ uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool {
return rr.Epoch == 1 && rr.Round == 1
})).Return(nil)
- uni.tracker.HandleLog(logBroadcast)
+ uni.tracker.HandleLog(testutils.Context(t), logBroadcast)
configDigest, epoch, round, err = uni.tracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -248,13 +247,13 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
logBroadcast2.On("RawLog").Return(rawLog2)
logBroadcast2.On("String").Return("").Maybe()
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- uni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
- uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool {
+ uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool {
return rr.Epoch == 1 && rr.Round == 9
})).Return(nil)
- uni.tracker.HandleLog(logBroadcast2)
+ uni.tracker.HandleLog(testutils.Context(t), logBroadcast2)
configDigest, epoch, round, err = uni.tracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -263,7 +262,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
assert.Equal(t, 9, int(round))
// Same round with lower epoch is ignored
- uni.tracker.HandleLog(logBroadcast)
+ uni.tracker.HandleLog(testutils.Context(t), logBroadcast)
configDigest, epoch, round, err = uni.tracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -277,13 +276,13 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
logBroadcast3.On("RawLog").Return(rawLog3).Maybe()
logBroadcast3.On("String").Return("").Maybe()
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- uni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
- uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool {
+ uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool {
return rr.Epoch == 2 && rr.Round == 1
})).Return(nil)
- uni.tracker.HandleLog(logBroadcast3)
+ uni.tracker.HandleLog(testutils.Context(t), logBroadcast3)
configDigest, epoch, round, err = uni.tracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -301,9 +300,9 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
logBroadcast.On("String").Return("").Maybe()
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything).Return(errors.New("something exploded"))
+ uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("something exploded"))
- uni.tracker.HandleLog(logBroadcast)
+ uni.tracker.HandleLog(testutils.Context(t), logBroadcast)
configDigest, epoch, round, err := uni.tracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -331,7 +330,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
eventuallyCloseHeadBroadcaster := cltest.NewAwaiter()
uni.hb.On("Subscribe", uni.tracker).Return((*evmtypes.Head)(nil), func() { eventuallyCloseHeadBroadcaster.ItHappened() })
- uni.db.On("LoadLatestRoundRequested").Return(rr, nil)
+ uni.db.On("LoadLatestRoundRequested", mock.Anything).Return(rr, nil)
require.NoError(t, uni.tracker.Start(testutils.Context(t)))
diff --git a/core/services/ocr/database.go b/core/services/ocr/database.go
index 977c371c15d..95993de9d5c 100644
--- a/core/services/ocr/database.go
+++ b/core/services/ocr/database.go
@@ -11,17 +11,16 @@ import (
"github.com/pkg/errors"
"go.uber.org/multierr"
- "github.com/jmoiron/sqlx"
"github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting/types"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
type db struct {
- q pg.Q
+ ds sqlutil.DataSource
oracleSpecID int32
lggr logger.SugaredLogger
}
@@ -32,11 +31,9 @@ var (
)
// NewDB returns a new DB scoped to this oracleSpecID
-func NewDB(sqlxDB *sqlx.DB, oracleSpecID int32, lggr logger.Logger, cfg pg.QConfig) *db {
- namedLogger := lggr.Named("OCR.DB")
-
+func NewDB(ds sqlutil.DataSource, oracleSpecID int32, lggr logger.Logger) *db {
return &db{
- q: pg.NewQ(sqlxDB, namedLogger, cfg),
+ ds: ds,
oracleSpecID: oracleSpecID,
lggr: logger.Sugared(lggr),
}
@@ -54,7 +51,7 @@ func (d *db) ReadState(ctx context.Context, cd ocrtypes.ConfigDigest) (ps *ocrty
var tmp []int64
var highestSentEpochTmp int64
- err = d.q.QueryRowxContext(ctx, stmt, d.oracleSpecID, cd).Scan(&ps.Epoch, &highestSentEpochTmp, pq.Array(&tmp))
+ err = d.ds.QueryRowxContext(ctx, stmt, d.oracleSpecID, cd).Scan(&ps.Epoch, &highestSentEpochTmp, pq.Array(&tmp))
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
@@ -90,7 +87,9 @@ func (d *db) WriteState(ctx context.Context, cd ocrtypes.ConfigDigest, state ocr
NOW()
)
`
- _, err := d.q.WithOpts(pg.WithLongQueryTimeout()).ExecContext(
+ ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute)
+ defer cancel()
+ _, err := d.ds.ExecContext(
ctx, stmt, d.oracleSpecID, cd, state.Epoch, state.HighestSentEpoch, pq.Array(&highestReceivedEpoch),
)
@@ -109,7 +108,7 @@ func (d *db) ReadConfig(ctx context.Context) (c *ocrtypes.ContractConfig, err er
var signers [][]byte
var transmitters [][]byte
- err = d.q.QueryRowContext(ctx, stmt, d.oracleSpecID).Scan(
+ err = d.ds.QueryRowxContext(ctx, stmt, d.oracleSpecID).Scan(
&c.ConfigDigest,
(*pq.ByteaArray)(&signers),
(*pq.ByteaArray)(&transmitters),
@@ -155,7 +154,7 @@ func (d *db) WriteConfig(ctx context.Context, c ocrtypes.ContractConfig) error {
encoded = EXCLUDED.encoded,
updated_at = NOW()
`
- _, err := d.q.ExecContext(ctx, stmt, d.oracleSpecID, c.ConfigDigest, pq.ByteaArray(signers), pq.ByteaArray(transmitters), c.Threshold, int(c.EncodedConfigVersion), c.Encoded)
+ _, err := d.ds.ExecContext(ctx, stmt, d.oracleSpecID, c.ConfigDigest, pq.ByteaArray(signers), pq.ByteaArray(transmitters), c.Threshold, int(c.EncodedConfigVersion), c.Encoded)
return errors.Wrap(err, "WriteConfig failed")
}
@@ -201,14 +200,14 @@ func (d *db) StorePendingTransmission(ctx context.Context, k ocrtypes.ReportTime
updated_at = NOW()
`
- _, err := d.q.ExecContext(ctx, stmt, d.oracleSpecID, k.ConfigDigest, k.Epoch, k.Round, p.Time, median, p.SerializedReport, pq.ByteaArray(rs), pq.ByteaArray(ss), p.Vs[:])
+ _, err := d.ds.ExecContext(ctx, stmt, d.oracleSpecID, k.ConfigDigest, k.Epoch, k.Round, p.Time, median, p.SerializedReport, pq.ByteaArray(rs), pq.ByteaArray(ss), p.Vs[:])
return errors.Wrap(err, "StorePendingTransmission failed")
}
func (d *db) PendingTransmissionsWithConfigDigest(ctx context.Context, cd ocrtypes.ConfigDigest) (map[ocrtypes.ReportTimestamp]ocrtypes.PendingTransmission, error) {
//nolint sqlclosecheck false positive
- rows, err := d.q.QueryContext(ctx, `
+ rows, err := d.ds.QueryContext(ctx, `
SELECT
config_digest,
epoch,
@@ -269,7 +268,9 @@ WHERE ocr_oracle_spec_id = $1 AND config_digest = $2
}
func (d *db) DeletePendingTransmission(ctx context.Context, k ocrtypes.ReportTimestamp) (err error) {
- _, err = d.q.WithOpts(pg.WithLongQueryTimeout()).ExecContext(ctx, `
+ ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute)
+ defer cancel()
+ _, err = d.ds.ExecContext(ctx, `
DELETE FROM ocr_pending_transmissions
WHERE ocr_oracle_spec_id = $1 AND config_digest = $2 AND epoch = $3 AND round = $4
`, d.oracleSpecID, k.ConfigDigest, k.Epoch, k.Round)
@@ -280,7 +281,9 @@ WHERE ocr_oracle_spec_id = $1 AND config_digest = $2 AND epoch = $3 AND round =
}
func (d *db) DeletePendingTransmissionsOlderThan(ctx context.Context, t time.Time) (err error) {
- _, err = d.q.WithOpts(pg.WithLongQueryTimeout()).ExecContext(ctx, `
+ ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute)
+ defer cancel()
+ _, err = d.ds.ExecContext(ctx, `
DELETE FROM ocr_pending_transmissions
WHERE ocr_oracle_spec_id = $1 AND time < $2
`, d.oracleSpecID, t)
@@ -290,12 +293,12 @@ WHERE ocr_oracle_spec_id = $1 AND time < $2
return
}
-func (d *db) SaveLatestRoundRequested(tx pg.Queryer, rr offchainaggregator.OffchainAggregatorRoundRequested) error {
+func (d *db) SaveLatestRoundRequested(ctx context.Context, tx sqlutil.DataSource, rr offchainaggregator.OffchainAggregatorRoundRequested) error {
rawLog, err := json.Marshal(rr.Raw)
if err != nil {
return errors.Wrap(err, "could not marshal log as JSON")
}
- _, err = tx.Exec(`
+ _, err = tx.ExecContext(ctx, `
INSERT INTO ocr_latest_round_requested (ocr_oracle_spec_id, requester, config_digest, epoch, round, raw)
VALUES ($1,$2,$3,$4,$5,$6) ON CONFLICT (ocr_oracle_spec_id) DO UPDATE SET
requester = EXCLUDED.requester,
@@ -308,8 +311,8 @@ VALUES ($1,$2,$3,$4,$5,$6) ON CONFLICT (ocr_oracle_spec_id) DO UPDATE SET
return errors.Wrap(err, "could not save latest round requested")
}
-func (d *db) LoadLatestRoundRequested() (rr offchainaggregator.OffchainAggregatorRoundRequested, err error) {
- rows, err := d.q.Query(`
+func (d *db) LoadLatestRoundRequested(ctx context.Context) (rr offchainaggregator.OffchainAggregatorRoundRequested, err error) {
+ rows, err := d.ds.QueryContext(ctx, `
SELECT requester, config_digest, epoch, round, raw
FROM ocr_latest_round_requested
WHERE ocr_oracle_spec_id = $1
diff --git a/core/services/ocr/database_test.go b/core/services/ocr/database_test.go
index 5ccf257b2bb..8b8d64c49c9 100644
--- a/core/services/ocr/database_test.go
+++ b/core/services/ocr/database_test.go
@@ -410,7 +410,8 @@ func Test_DB_LatestRoundRequested(t *testing.T) {
}
t.Run("saves latest round requested", func(t *testing.T) {
- err := odb.SaveLatestRoundRequested(sqlDB, rr)
+ ctx := testutils.Context(t)
+ err := odb.SaveLatestRoundRequested(ctx, sqlDB, rr)
require.NoError(t, err)
rawLog.Index = 42
@@ -424,17 +425,18 @@ func Test_DB_LatestRoundRequested(t *testing.T) {
Raw: rawLog,
}
- err = odb.SaveLatestRoundRequested(sqlDB, rr)
+ err = odb.SaveLatestRoundRequested(ctx, sqlDB, rr)
require.NoError(t, err)
})
t.Run("loads latest round requested", func(t *testing.T) {
+ ctx := testutils.Context(t)
// There is no round for db2
- lrr, err := odb2.LoadLatestRoundRequested()
+ lrr, err := odb2.LoadLatestRoundRequested(ctx)
require.NoError(t, err)
require.Equal(t, 0, int(lrr.Epoch))
- lrr, err = odb.LoadLatestRoundRequested()
+ lrr, err = odb.LoadLatestRoundRequested(ctx)
require.NoError(t, err)
assert.Equal(t, rr, lrr)
diff --git a/core/services/ocr/delegate.go b/core/services/ocr/delegate.go
index bcdda397e20..b16ede8089f 100644
--- a/core/services/ocr/delegate.go
+++ b/core/services/ocr/delegate.go
@@ -28,7 +28,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
"github.com/smartcontractkit/chainlink/v2/core/services/telemetry"
@@ -82,10 +81,10 @@ func (d *Delegate) JobType() job.Type {
return job.OffchainReporting
}
-func (d *Delegate) BeforeJobCreated(spec job.Job) {}
-func (d *Delegate) AfterJobCreated(spec job.Job) {}
-func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) BeforeJobCreated(spec job.Job) {}
+func (d *Delegate) AfterJobCreated(spec job.Job) {}
+func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec returns the OCR services that need to run for this job
func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []job.ServiceCtx, err error) {
@@ -121,7 +120,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []
return nil, errors.Wrap(err, "could not instantiate NewOffchainAggregatorCaller")
}
- ocrDB := NewDB(d.db, concreteSpec.ID, lggr, d.cfg)
+ ocrDB := NewDB(d.db, concreteSpec.ID, lggr)
tracker := NewOCRContractTracker(
contract,
@@ -134,7 +133,6 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []
d.db,
ocrDB,
chain.Config().EVM(),
- chain.Config().Database(),
chain.HeadBroadcaster(),
d.mailMon,
)
@@ -199,7 +197,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []
}
cfg := chain.Config()
- strategy := txmgrcommon.NewQueueingTxStrategy(jb.ExternalJobID, cfg.OCR().DefaultTransactionQueueDepth(), cfg.Database().DefaultQueryTimeout())
+ strategy := txmgrcommon.NewQueueingTxStrategy(jb.ExternalJobID, cfg.OCR().DefaultTransactionQueueDepth())
var checker txmgr.TransmitCheckerSpec
if chain.Config().OCR().SimulateTransactions() {
diff --git a/core/services/ocr/helpers_internal_test.go b/core/services/ocr/helpers_internal_test.go
index 57b669ef401..c6a3d1ac401 100644
--- a/core/services/ocr/helpers_internal_test.go
+++ b/core/services/ocr/helpers_internal_test.go
@@ -5,7 +5,6 @@ import (
"github.com/jmoiron/sqlx"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
)
@@ -14,5 +13,5 @@ func (c *ConfigOverriderImpl) ExportedUpdateFlagsStatus() error {
}
func NewTestDB(t *testing.T, sqldb *sqlx.DB, oracleSpecID int32) *db {
- return NewDB(sqldb, oracleSpecID, logger.TestLogger(t), pgtest.NewQConfig(true))
+ return NewDB(sqldb, oracleSpecID, logger.TestLogger(t))
}
diff --git a/core/services/ocr/mocks/ocr_contract_tracker_db.go b/core/services/ocr/mocks/ocr_contract_tracker_db.go
index 6724e418014..42eebf939d7 100644
--- a/core/services/ocr/mocks/ocr_contract_tracker_db.go
+++ b/core/services/ocr/mocks/ocr_contract_tracker_db.go
@@ -3,11 +3,13 @@
package mocks
import (
+ context "context"
+
mock "github.com/stretchr/testify/mock"
offchainaggregator "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator"
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
)
// OCRContractTrackerDB is an autogenerated mock type for the OCRContractTrackerDB type
@@ -15,9 +17,9 @@ type OCRContractTrackerDB struct {
mock.Mock
}
-// LoadLatestRoundRequested provides a mock function with given fields:
-func (_m *OCRContractTrackerDB) LoadLatestRoundRequested() (offchainaggregator.OffchainAggregatorRoundRequested, error) {
- ret := _m.Called()
+// LoadLatestRoundRequested provides a mock function with given fields: ctx
+func (_m *OCRContractTrackerDB) LoadLatestRoundRequested(ctx context.Context) (offchainaggregator.OffchainAggregatorRoundRequested, error) {
+ ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for LoadLatestRoundRequested")
@@ -25,17 +27,17 @@ func (_m *OCRContractTrackerDB) LoadLatestRoundRequested() (offchainaggregator.O
var r0 offchainaggregator.OffchainAggregatorRoundRequested
var r1 error
- if rf, ok := ret.Get(0).(func() (offchainaggregator.OffchainAggregatorRoundRequested, error)); ok {
- return rf()
+ if rf, ok := ret.Get(0).(func(context.Context) (offchainaggregator.OffchainAggregatorRoundRequested, error)); ok {
+ return rf(ctx)
}
- if rf, ok := ret.Get(0).(func() offchainaggregator.OffchainAggregatorRoundRequested); ok {
- r0 = rf()
+ if rf, ok := ret.Get(0).(func(context.Context) offchainaggregator.OffchainAggregatorRoundRequested); ok {
+ r0 = rf(ctx)
} else {
r0 = ret.Get(0).(offchainaggregator.OffchainAggregatorRoundRequested)
}
- if rf, ok := ret.Get(1).(func() error); ok {
- r1 = rf()
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
@@ -43,17 +45,17 @@ func (_m *OCRContractTrackerDB) LoadLatestRoundRequested() (offchainaggregator.O
return r0, r1
}
-// SaveLatestRoundRequested provides a mock function with given fields: tx, rr
-func (_m *OCRContractTrackerDB) SaveLatestRoundRequested(tx pg.Queryer, rr offchainaggregator.OffchainAggregatorRoundRequested) error {
- ret := _m.Called(tx, rr)
+// SaveLatestRoundRequested provides a mock function with given fields: ctx, tx, rr
+func (_m *OCRContractTrackerDB) SaveLatestRoundRequested(ctx context.Context, tx sqlutil.DataSource, rr offchainaggregator.OffchainAggregatorRoundRequested) error {
+ ret := _m.Called(ctx, tx, rr)
if len(ret) == 0 {
panic("no return value specified for SaveLatestRoundRequested")
}
var r0 error
- if rf, ok := ret.Get(0).(func(pg.Queryer, offchainaggregator.OffchainAggregatorRoundRequested) error); ok {
- r0 = rf(tx, rr)
+ if rf, ok := ret.Get(0).(func(context.Context, sqlutil.DataSource, offchainaggregator.OffchainAggregatorRoundRequested) error); ok {
+ r0 = rf(ctx, tx, rr)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go
index 7b4200efd68..da6d6a1b6e7 100644
--- a/core/services/ocr2/delegate.go
+++ b/core/services/ocr2/delegate.go
@@ -27,6 +27,7 @@ import (
ocr2keepers21config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config"
ocr2keepers21 "github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin"
"github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/config/env"
"github.com/smartcontractkit/chainlink-vrf/altbn_128"
@@ -109,7 +110,8 @@ type RelayGetter interface {
Get(id relay.ID) (loop.Relayer, error)
}
type Delegate struct {
- db *sqlx.DB
+ db *sqlx.DB // legacy: prefer to use ds instead
+ ds sqlutil.DataSource
jobORM job.ORM
bridgeORM bridges.ORM
mercuryORM evmmercury.ORM
@@ -223,6 +225,7 @@ var _ job.Delegate = (*Delegate)(nil)
func NewDelegate(
db *sqlx.DB,
+ ds sqlutil.DataSource,
jobORM job.ORM,
bridgeORM bridges.ORM,
mercuryORM evmmercury.ORM,
@@ -243,6 +246,7 @@ func NewDelegate(
) *Delegate {
return &Delegate{
db: db,
+ ds: ds,
jobORM: jobORM,
bridgeORM: bridgeORM,
mercuryORM: mercuryORM,
@@ -274,7 +278,7 @@ func (d *Delegate) BeforeJobCreated(spec job.Job) {
}
func (d *Delegate) AfterJobCreated(spec job.Job) {}
func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, jb job.Job, q pg.Queryer) error {
+func (d *Delegate) OnDeleteJob(ctx context.Context, jb job.Job) error {
// If the job spec is malformed in any way, we report the error but return nil so that
// the job deletion itself isn't blocked.
@@ -291,13 +295,13 @@ func (d *Delegate) OnDeleteJob(ctx context.Context, jb job.Job, q pg.Queryer) er
}
// we only have clean to do for the EVM
if rid.Network == relay.EVM {
- return d.cleanupEVM(ctx, jb, q, rid)
+ return d.cleanupEVM(ctx, jb, rid)
}
return nil
}
// cleanupEVM is a helper for clean up EVM specific state when a job is deleted
-func (d *Delegate) cleanupEVM(ctx context.Context, jb job.Job, q pg.Queryer, relayID relay.ID) error {
+func (d *Delegate) cleanupEVM(ctx context.Context, jb job.Job, relayID relay.ID) error {
// If UnregisterFilter returns an
// error, that means it failed to remove a valid active filter from the db. We do abort the job deletion
// in that case, since it should be easy for the user to retry and will avoid leaving the db in
@@ -1669,8 +1673,7 @@ func (d *Delegate) newServicesOCR2Functions(
Job: jb,
JobORM: d.jobORM,
BridgeORM: d.bridgeORM,
- QConfig: d.cfg.Database(),
- DB: d.db,
+ DS: d.ds,
Chain: chain,
ContractID: spec.ContractID,
Logger: lggr,
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 ab4b114906e..ae9bf5f01cd 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
@@ -422,9 +422,10 @@ func AddBootstrapJob(t *testing.T, app *cltest.TestApplication, contractAddress
}
func AddOCR2Job(t *testing.T, app *cltest.TestApplication, contractAddress common.Address, keyBundleID string, transmitter common.Address, bridgeURL string) job.Job {
+ ctx := testutils.Context(t)
u, err := url.Parse(bridgeURL)
require.NoError(t, err)
- require.NoError(t, app.BridgeORM().CreateBridgeType(&bridges.BridgeType{
+ require.NoError(t, app.BridgeORM().CreateBridgeType(ctx, &bridges.BridgeType{
Name: "ea_bridge",
URL: models.WebURL(*u),
}))
diff --git a/core/services/ocr2/plugins/functions/plugin.go b/core/services/ocr2/plugins/functions/plugin.go
index 92b15892885..d6ffa1a3f06 100644
--- a/core/services/ocr2/plugins/functions/plugin.go
+++ b/core/services/ocr2/plugins/functions/plugin.go
@@ -8,13 +8,13 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
- "github.com/jmoiron/sqlx"
"github.com/jonboulle/clockwork"
"github.com/pkg/errors"
"github.com/smartcontractkit/libocr/commontypes"
libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
@@ -31,7 +31,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config"
s4_plugin "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/s4"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/threshold"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
evmrelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/services/s4"
)
@@ -40,8 +39,7 @@ type FunctionsServicesConfig struct {
Job job.Job
JobORM job.ORM
BridgeORM bridges.ORM
- QConfig pg.QConfig
- DB *sqlx.DB
+ DS sqlutil.DataSource
Chain legacyevm.Chain
ContractID string
Logger logger.Logger
@@ -63,8 +61,8 @@ const (
// Create all OCR2 plugin Oracles and all extra services needed to run a Functions job.
func NewFunctionsServices(ctx context.Context, functionsOracleArgs, thresholdOracleArgs, s4OracleArgs *libocr2.OCR2OracleArgs, conf *FunctionsServicesConfig) ([]job.ServiceCtx, error) {
- pluginORM := functions.NewORM(conf.DB, conf.Logger, conf.QConfig, common.HexToAddress(conf.ContractID))
- s4ORM := s4.NewCachedORMWrapper(s4.NewPostgresORM(conf.DB, conf.Logger, conf.QConfig, s4.SharedTableName, FunctionsS4Namespace), conf.Logger)
+ pluginORM := functions.NewORM(conf.DS, common.HexToAddress(conf.ContractID))
+ s4ORM := s4.NewCachedORMWrapper(s4.NewPostgresORM(conf.DS, s4.SharedTableName, FunctionsS4Namespace), conf.Logger)
var pluginConfig config.PluginConfig
if err := json.Unmarshal(conf.Job.OCR2OracleSpec.PluginConfig.Bytes(), &pluginConfig); err != nil {
@@ -155,7 +153,7 @@ func NewFunctionsServices(ctx context.Context, functionsOracleArgs, thresholdOra
allServices = append(allServices, job.NewServiceAdapter(functionsReportingPluginOracle))
if pluginConfig.GatewayConnectorConfig != nil && s4Storage != nil && pluginConfig.OnchainAllowlist != nil && pluginConfig.RateLimiter != nil && pluginConfig.OnchainSubscriptions != nil {
- allowlistORM, err := gwAllowlist.NewORM(conf.DB, conf.Logger, conf.QConfig, pluginConfig.OnchainAllowlist.ContractAddress)
+ allowlistORM, err := gwAllowlist.NewORM(conf.DS, conf.Logger, pluginConfig.OnchainAllowlist.ContractAddress)
if err != nil {
return nil, errors.Wrap(err, "failed to create allowlist ORM")
}
@@ -167,7 +165,7 @@ func NewFunctionsServices(ctx context.Context, functionsOracleArgs, thresholdOra
if err2 != nil {
return nil, errors.Wrap(err, "failed to create a RateLimiter")
}
- subscriptionsORM, err := gwSubscriptions.NewORM(conf.DB, conf.Logger, conf.QConfig, pluginConfig.OnchainSubscriptions.ContractAddress)
+ subscriptionsORM, err := gwSubscriptions.NewORM(conf.DS, conf.Logger, pluginConfig.OnchainSubscriptions.ContractAddress)
if err != nil {
return nil, errors.Wrap(err, "failed to create subscriptions ORM")
}
diff --git a/core/services/ocr2/plugins/functions/reporting.go b/core/services/ocr2/plugins/functions/reporting.go
index 36e8a882734..d9d68ec9097 100644
--- a/core/services/ocr2/plugins/functions/reporting.go
+++ b/core/services/ocr2/plugins/functions/reporting.go
@@ -18,7 +18,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/functions"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/encoding"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
type FunctionsReportingPluginFactory struct {
@@ -151,7 +150,7 @@ func (r *functionsReporting) Query(ctx context.Context, ts types.ReportTimestamp
"oracleID": r.genericConfig.OracleID,
})
maxBatchSize := r.specificConfig.Config.GetMaxRequestBatchSize()
- results, err := r.pluginORM.FindOldestEntriesByState(functions.RESULT_READY, maxBatchSize, pg.WithParentCtx(ctx))
+ results, err := r.pluginORM.FindOldestEntriesByState(ctx, functions.RESULT_READY, maxBatchSize)
if err != nil {
return nil, err
}
@@ -222,7 +221,7 @@ func (r *functionsReporting) Observation(ctx context.Context, ts types.ReportTim
continue
}
processedIds[id] = true
- localResult, err2 := r.pluginORM.FindById(id, pg.WithParentCtx(ctx))
+ localResult, err2 := r.pluginORM.FindById(ctx, id)
if err2 != nil {
r.logger.Debug("FunctionsReporting Observation can't find request from query", commontypes.LogFields{
"requestID": formatRequestId(id[:]),
@@ -429,14 +428,14 @@ func (r *functionsReporting) ShouldAcceptFinalizedReport(ctx context.Context, ts
r.logger.Error("FunctionsReporting ShouldAcceptFinalizedReport: invalid ID", commontypes.LogFields{"requestID": reqIdStr, "err": err})
continue
}
- _, err = r.pluginORM.FindById(id, pg.WithParentCtx(ctx))
+ _, err = r.pluginORM.FindById(ctx, id)
if err != nil {
// TODO: Differentiate between ID not found and other ORM errors (https://smartcontract-it.atlassian.net/browse/DRO-215)
r.logger.Warn("FunctionsReporting ShouldAcceptFinalizedReport: request doesn't exist locally! Accepting anyway.", commontypes.LogFields{"requestID": reqIdStr})
needTransmissionIds = append(needTransmissionIds, reqIdStr)
continue
}
- err = r.pluginORM.SetFinalized(id, item.Result, item.Error, pg.WithParentCtx(ctx)) // validates state transition
+ err = r.pluginORM.SetFinalized(ctx, id, item.Result, item.Error) // validates state transition
if err != nil {
r.logger.Debug("FunctionsReporting ShouldAcceptFinalizedReport: state couldn't be changed to FINALIZED. Not transmitting.", commontypes.LogFields{"requestID": reqIdStr, "err": err})
continue
@@ -490,7 +489,7 @@ func (r *functionsReporting) ShouldTransmitAcceptedReport(ctx context.Context, t
r.logger.Error("FunctionsReporting ShouldAcceptFinalizedReport: invalid ID", commontypes.LogFields{"requestID": reqIdStr, "err": err})
continue
}
- request, err := r.pluginORM.FindById(id, pg.WithParentCtx(ctx))
+ request, err := r.pluginORM.FindById(ctx, id)
if err != nil {
r.logger.Warn("FunctionsReporting ShouldTransmitAcceptedReport: request doesn't exist locally! Transmitting anyway.", commontypes.LogFields{"requestID": reqIdStr, "err": err})
needTransmissionIds = append(needTransmissionIds, reqIdStr)
diff --git a/core/services/ocr2/plugins/functions/reporting_test.go b/core/services/ocr2/plugins/functions/reporting_test.go
index 5b9f59ccb23..7d6686a0b4f 100644
--- a/core/services/ocr2/plugins/functions/reporting_test.go
+++ b/core/services/ocr2/plugins/functions/reporting_test.go
@@ -134,7 +134,7 @@ func TestFunctionsReporting_Query(t *testing.T) {
const batchSize = 10
plugin, orm, _, _ := preparePlugin(t, batchSize, 0)
reqs := []functions_srv.Request{newRequest(), newRequest()}
- orm.On("FindOldestEntriesByState", functions_srv.RESULT_READY, uint32(batchSize), mock.Anything).Return(reqs, nil)
+ orm.On("FindOldestEntriesByState", mock.Anything, functions_srv.RESULT_READY, uint32(batchSize), mock.Anything).Return(reqs, nil)
q, err := plugin.Query(testutils.Context(t), types.ReportTimestamp{})
require.NoError(t, err)
@@ -154,7 +154,7 @@ func TestFunctionsReporting_Query_HandleCoordinatorMismatch(t *testing.T) {
reqs := []functions_srv.Request{newRequest(), newRequest()}
reqs[0].CoordinatorContractAddress = &common.Address{1}
reqs[1].CoordinatorContractAddress = &common.Address{2}
- orm.On("FindOldestEntriesByState", functions_srv.RESULT_READY, uint32(batchSize), mock.Anything).Return(reqs, nil)
+ orm.On("FindOldestEntriesByState", mock.Anything, functions_srv.RESULT_READY, uint32(batchSize), mock.Anything).Return(reqs, nil)
q, err := plugin.Query(testutils.Context(t), types.ReportTimestamp{})
require.NoError(t, err)
@@ -177,11 +177,11 @@ func TestFunctionsReporting_Observation(t *testing.T) {
req4 := newRequestTimedOut()
nonexistentId := newRequestID()
- orm.On("FindById", req1.RequestID, mock.Anything).Return(&req1, nil)
- orm.On("FindById", req2.RequestID, mock.Anything).Return(&req2, nil)
- orm.On("FindById", req3.RequestID, mock.Anything).Return(&req3, nil)
- orm.On("FindById", req4.RequestID, mock.Anything).Return(&req4, nil)
- orm.On("FindById", nonexistentId, mock.Anything).Return(nil, errors.New("nonexistent ID"))
+ orm.On("FindById", mock.Anything, req1.RequestID, mock.Anything).Return(&req1, nil)
+ orm.On("FindById", mock.Anything, req2.RequestID, mock.Anything).Return(&req2, nil)
+ orm.On("FindById", mock.Anything, req3.RequestID, mock.Anything).Return(&req3, nil)
+ orm.On("FindById", mock.Anything, req4.RequestID, mock.Anything).Return(&req4, nil)
+ orm.On("FindById", mock.Anything, nonexistentId, mock.Anything).Return(nil, errors.New("nonexistent ID"))
// Query asking for 5 requests (with duplicates), out of which:
// - two are ready
@@ -209,7 +209,7 @@ func TestFunctionsReporting_Observation_IncorrectQuery(t *testing.T) {
req1 := newRequestWithResult([]byte("abc"))
invalidId := []byte("invalid")
- orm.On("FindById", req1.RequestID, mock.Anything).Return(&req1, nil)
+ orm.On("FindById", mock.Anything, req1.RequestID, mock.Anything).Return(&req1, nil)
// Query asking for 3 requests (with duplicates), out of which:
// - two are invalid
@@ -441,13 +441,13 @@ func TestFunctionsReporting_ShouldAcceptFinalizedReport(t *testing.T) {
req3 := newRequestFinalized()
req4 := newRequestTimedOut()
- orm.On("FindById", req1.RequestID, mock.Anything).Return(nil, errors.New("nonexistent ID"))
- orm.On("FindById", req2.RequestID, mock.Anything).Return(&req2, nil)
- orm.On("SetFinalized", req2.RequestID, mock.Anything, mock.Anything, mock.Anything).Return(nil)
- orm.On("FindById", req3.RequestID, mock.Anything).Return(&req3, nil)
- orm.On("SetFinalized", req3.RequestID, mock.Anything, mock.Anything, mock.Anything).Return(errors.New("same state"))
- orm.On("FindById", req4.RequestID, mock.Anything).Return(&req4, nil)
- orm.On("SetFinalized", req4.RequestID, mock.Anything, mock.Anything, mock.Anything).Return(errors.New("already timed out"))
+ orm.On("FindById", mock.Anything, req1.RequestID, mock.Anything).Return(nil, errors.New("nonexistent ID"))
+ orm.On("FindById", mock.Anything, req2.RequestID, mock.Anything).Return(&req2, nil)
+ orm.On("SetFinalized", mock.Anything, req2.RequestID, mock.Anything, mock.Anything, mock.Anything).Return(nil)
+ orm.On("FindById", mock.Anything, req3.RequestID, mock.Anything).Return(&req3, nil)
+ orm.On("SetFinalized", mock.Anything, req3.RequestID, mock.Anything, mock.Anything, mock.Anything).Return(errors.New("same state"))
+ orm.On("FindById", mock.Anything, req4.RequestID, mock.Anything).Return(&req4, nil)
+ orm.On("SetFinalized", mock.Anything, req4.RequestID, mock.Anything, mock.Anything, mock.Anything).Return(errors.New("already timed out"))
// Attempting to transmit 2 requests, out of which:
// - one was already accepted for transmission earlier
@@ -477,8 +477,8 @@ func TestFunctionsReporting_ShouldAcceptFinalizedReport_OffchainTransmission(t *
req1 := newRequestWithResult([]byte("abc"))
req1.OnchainMetadata = []byte(functions_srv.OffchainRequestMarker)
- orm.On("FindById", req1.RequestID, mock.Anything).Return(&req1, nil)
- orm.On("SetFinalized", req1.RequestID, mock.Anything, mock.Anything, mock.Anything).Return(nil)
+ orm.On("FindById", mock.Anything, req1.RequestID, mock.Anything).Return(&req1, nil)
+ orm.On("SetFinalized", mock.Anything, req1.RequestID, mock.Anything, mock.Anything, mock.Anything).Return(nil)
offchainTransmitter.On("TransmitReport", mock.Anything, mock.Anything).Return(nil)
should, err := plugin.ShouldAcceptFinalizedReport(testutils.Context(t), types.ReportTimestamp{}, getReportBytes(t, codec, req1))
@@ -496,11 +496,11 @@ func TestFunctionsReporting_ShouldTransmitAcceptedReport(t *testing.T) {
req4 := newRequestTimedOut()
req5 := newRequestConfirmed()
- orm.On("FindById", req1.RequestID, mock.Anything).Return(nil, errors.New("nonexistent ID"))
- orm.On("FindById", req2.RequestID, mock.Anything).Return(&req2, nil)
- orm.On("FindById", req3.RequestID, mock.Anything).Return(&req3, nil)
- orm.On("FindById", req4.RequestID, mock.Anything).Return(&req4, nil)
- orm.On("FindById", req5.RequestID, mock.Anything).Return(&req5, nil)
+ orm.On("FindById", mock.Anything, req1.RequestID, mock.Anything).Return(nil, errors.New("nonexistent ID"))
+ orm.On("FindById", mock.Anything, req2.RequestID, mock.Anything).Return(&req2, nil)
+ orm.On("FindById", mock.Anything, req3.RequestID, mock.Anything).Return(&req3, nil)
+ orm.On("FindById", mock.Anything, req4.RequestID, mock.Anything).Return(&req4, nil)
+ orm.On("FindById", mock.Anything, req5.RequestID, mock.Anything).Return(&req5, nil)
// Attempting to transmit 2 requests, out of which:
// - one was already confirmed on chain
diff --git a/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go b/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go
index 569d5b49364..02136583e49 100644
--- a/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go
+++ b/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go
@@ -36,6 +36,7 @@ answer;
`
func TestAdapter_Integration(t *testing.T) {
+ testutils.SkipShortDB(t)
logger := logger.TestLogger(t)
cfg := configtest.NewTestGeneralConfig(t)
url := cfg.Database().URL()
@@ -43,8 +44,8 @@ func TestAdapter_Integration(t *testing.T) {
require.NoError(t, err)
keystore := keystore.NewInMemory(db, utils.FastScryptParams, logger, cfg.Database())
- pipelineORM := pipeline.NewORM(db, logger, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- bridgesORM := bridges.NewORM(db, logger, cfg.Database())
+ pipelineORM := pipeline.NewORM(db, logger, cfg.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db)
jobORM := job.NewORM(db, pipelineORM, bridgesORM, keystore, logger, cfg.Database())
pr := pipeline.NewRunner(
pipelineORM,
diff --git a/core/services/ocr2/plugins/llo/helpers_test.go b/core/services/ocr2/plugins/llo/helpers_test.go
index 8112cf1b0ba..73f7fedc926 100644
--- a/core/services/ocr2/plugins/llo/helpers_test.go
+++ b/core/services/ocr2/plugins/llo/helpers_test.go
@@ -59,7 +59,7 @@ type request struct {
}
func (r request) TransmitterID() ocr2types.Account {
- return ocr2types.Account(fmt.Sprintf("%x", r.pk))
+ return ocr2types.Account(r.pk.String())
}
type mercuryServer struct {
@@ -114,7 +114,7 @@ func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.Publ
t.Fatalf("[MAIN] failed to listen: %v", err)
}
serverURL = lis.Addr().String()
- s := wsrpc.NewServer(wsrpc.Creds(srv.privKey, pubKeys))
+ s := wsrpc.NewServer(wsrpc.WithCreds(srv.privKey, pubKeys))
// Register mercury implementation with the wsrpc server
pb.RegisterMercuryServer(s, srv)
@@ -304,6 +304,7 @@ fromBlock = 1`,
}
func addOCRJobs(t *testing.T, streams []Stream, serverPubKey ed25519.PublicKey, serverURL string, verifierAddress common.Address, bootstrapPeerID string, bootstrapNodePort int, nodes []Node, configStoreAddress common.Address, clientPubKeys []ed25519.PublicKey, chainID *big.Int, fromBlock int) {
+ ctx := testutils.Context(t)
createBridge := func(name string, i int, p *big.Int, borm bridges.ORM) (bridgeName string) {
bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
b, err := io.ReadAll(req.Body)
@@ -319,7 +320,7 @@ func addOCRJobs(t *testing.T, streams []Stream, serverPubKey ed25519.PublicKey,
t.Cleanup(bridge.Close)
u, _ := url.Parse(bridge.URL)
bridgeName = fmt.Sprintf("bridge-%s-%d", name, i)
- require.NoError(t, borm.CreateBridgeType(&bridges.BridgeType{
+ require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{
Name: bridges.BridgeName(bridgeName),
URL: models.WebURL(*u),
}))
diff --git a/core/services/ocr2/plugins/llo/integration_test.go b/core/services/ocr2/plugins/llo/integration_test.go
index df77316e4dd..b6f752541f4 100644
--- a/core/services/ocr2/plugins/llo/integration_test.go
+++ b/core/services/ocr2/plugins/llo/integration_test.go
@@ -173,10 +173,10 @@ func TestIntegration_LLO(t *testing.T) {
t.Logf("Expect report from oracle %s", o.OracleIdentity.TransmitAccount)
seen[o.OracleIdentity.TransmitAccount] = make(map[llotypes.ChannelID]struct{})
}
-
for req := range reqs {
if _, exists := seen[req.TransmitterID()]; !exists {
// oracle already reported on all channels; discard
+ // if this test timeouts, check for expected transmitter ID
continue
}
@@ -188,7 +188,7 @@ func TestIntegration_LLO(t *testing.T) {
t.Fatalf("FAIL: expected payload %#v to contain 'report'", v)
}
- t.Logf("Got report from oracle %x with format: %d", req.pk, req.req.ReportFormat)
+ t.Logf("Got report from oracle %s with format: %d", req.pk, req.req.ReportFormat)
var r datastreamsllo.Report
@@ -199,7 +199,7 @@ func TestIntegration_LLO(t *testing.T) {
r, err = (datastreamsllo.JSONReportCodec{}).Decode(report.([]byte))
require.NoError(t, err, "expected valid JSON")
case uint32(llotypes.ReportFormatEVM):
- t.Logf("Got report (EVM) from oracle %x: 0x%x", req.pk, report.([]byte))
+ t.Logf("Got report (EVM) from oracle %s: 0x%x", req.pk, report.([]byte))
var err error
r, err = (lloevm.ReportCodec{}).Decode(report.([]byte))
require.NoError(t, err, "expected valid EVM encoding")
diff --git a/core/services/ocr2/plugins/mercury/helpers_test.go b/core/services/ocr2/plugins/mercury/helpers_test.go
index 43d709453b7..fbb51557eb1 100644
--- a/core/services/ocr2/plugins/mercury/helpers_test.go
+++ b/core/services/ocr2/plugins/mercury/helpers_test.go
@@ -103,7 +103,7 @@ func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.Publ
t.Fatalf("[MAIN] failed to listen: %v", err)
}
serverURL = lis.Addr().String()
- s := wsrpc.NewServer(wsrpc.Creds(srv.privKey, pubKeys))
+ s := wsrpc.NewServer(wsrpc.WithCreds(srv.privKey, pubKeys))
// Register mercury implementation with the wsrpc server
pb.RegisterMercuryServer(s, srv)
diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go
index e4ac5dd7c5c..2339117d4e3 100644
--- a/core/services/ocr2/plugins/mercury/integration_test.go
+++ b/core/services/ocr2/plugins/mercury/integration_test.go
@@ -132,6 +132,7 @@ func TestIntegration_MercuryV1(t *testing.T) {
}
func integration_MercuryV1(t *testing.T) {
+ ctx := testutils.Context(t)
var logObservers []*observer.ObservedLogs
t.Cleanup(func() {
detectPanicLogs(t, logObservers)
@@ -236,7 +237,7 @@ func integration_MercuryV1(t *testing.T) {
t.Cleanup(bridge.Close)
u, _ := url.Parse(bridge.URL)
bridgeName = fmt.Sprintf("bridge-%s-%d", name, i)
- require.NoError(t, borm.CreateBridgeType(&bridges.BridgeType{
+ require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{
Name: bridges.BridgeName(bridgeName),
URL: models.WebURL(*u),
}))
@@ -474,6 +475,7 @@ func TestIntegration_MercuryV2(t *testing.T) {
}
func integration_MercuryV2(t *testing.T) {
+ ctx := testutils.Context(t)
var logObservers []*observer.ObservedLogs
t.Cleanup(func() {
detectPanicLogs(t, logObservers)
@@ -590,7 +592,7 @@ func integration_MercuryV2(t *testing.T) {
t.Cleanup(bridge.Close)
u, _ := url.Parse(bridge.URL)
bridgeName = fmt.Sprintf("bridge-%s-%d", name, i)
- require.NoError(t, borm.CreateBridgeType(&bridges.BridgeType{
+ require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{
Name: bridges.BridgeName(bridgeName),
URL: models.WebURL(*u),
}))
@@ -748,6 +750,7 @@ func TestIntegration_MercuryV3(t *testing.T) {
}
func integration_MercuryV3(t *testing.T) {
+ ctx := testutils.Context(t)
var logObservers []*observer.ObservedLogs
t.Cleanup(func() {
detectPanicLogs(t, logObservers)
@@ -878,7 +881,7 @@ func integration_MercuryV3(t *testing.T) {
t.Cleanup(bridge.Close)
u, _ := url.Parse(bridge.URL)
bridgeName = fmt.Sprintf("bridge-%s-%d", name, i)
- require.NoError(t, borm.CreateBridgeType(&bridges.BridgeType{
+ require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{
Name: bridges.BridgeName(bridgeName),
URL: models.WebURL(*u),
}))
diff --git a/core/services/ocr2/plugins/mercury/plugin_test.go b/core/services/ocr2/plugins/mercury/plugin_test.go
index 3934105a390..131f51af4b4 100644
--- a/core/services/ocr2/plugins/mercury/plugin_test.go
+++ b/core/services/ocr2/plugins/mercury/plugin_test.go
@@ -26,7 +26,6 @@ import (
libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus"
libocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types"
@@ -279,7 +278,7 @@ var _ plugins.RegistrarConfig = (*testRegistrarConfig)(nil)
type testDataSourceORM struct{}
// LatestReport implements types.DataSourceORM.
-func (*testDataSourceORM) LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) {
+func (*testDataSourceORM) LatestReport(ctx context.Context, feedID [32]byte) (report []byte, err error) {
return []byte{1, 2, 3}, nil
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry_test.go
index 3de22e507c7..592563f0b04 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry_test.go
@@ -12,7 +12,7 @@ import (
ocr2keepers "github.com/smartcontractkit/chainlink-automation/pkg/v2"
- commonmocks "github.com/smartcontractkit/chainlink/v2/common/mocks"
+ htmocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
@@ -46,7 +46,7 @@ func TestGetActiveUpkeepKeys(t *testing.T) {
actives[id] = activeUpkeep{ID: idNum}
}
- mht := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
+ mht := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
rg := &EvmRegistry{
HeadProvider: HeadProvider{
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber_test.go
index b984101bc16..fefbda77cd7 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber_test.go
@@ -11,7 +11,7 @@ import (
ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation"
- commonmocks "github.com/smartcontractkit/chainlink/v2/common/mocks"
+ htmocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
@@ -275,7 +275,7 @@ func TestBlockSubscriber_Cleanup(t *testing.T) {
func TestBlockSubscriber_Start(t *testing.T) {
lggr := logger.TestLogger(t)
- hb := commonmocks.NewHeadBroadcaster[*evmtypes.Head, common.Hash](t)
+ hb := htmocks.NewHeadBroadcaster[*evmtypes.Head, common.Hash](t)
hb.On("Subscribe", mock.Anything).Return(&evmtypes.Head{Number: 42}, func() {})
lp := new(mocks.LogPoller)
lp.On("LatestBlock", mock.Anything).Return(logpoller.LogPollerBlock{BlockNumber: 100}, nil)
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v02/v02_request_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v02/v02_request_test.go
index c7fd7982904..8fc55abc7e7 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v02/v02_request_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v02/v02_request_test.go
@@ -101,6 +101,7 @@ func setupClient(t *testing.T) *client {
}
func TestV02_SingleFeedRequest(t *testing.T) {
+ t.Parallel()
upkeepId := big.NewInt(123456789)
tests := []struct {
name string
@@ -382,6 +383,7 @@ func TestV02_SingleFeedRequest(t *testing.T) {
}
func TestV02_DoMercuryRequestV02(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
tests := []struct {
@@ -624,6 +626,7 @@ func TestV02_DoMercuryRequestV02(t *testing.T) {
}
func TestV02_DoMercuryRequestV02_MultipleFeedsSuccess(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
@@ -665,6 +668,7 @@ func TestV02_DoMercuryRequestV02_MultipleFeedsSuccess(t *testing.T) {
}
func TestV02_DoMercuryRequestV02_Timeout(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
@@ -719,6 +723,7 @@ func TestV02_DoMercuryRequestV02_Timeout(t *testing.T) {
}
func TestV02_DoMercuryRequestV02_OneFeedSuccessOneFeedPipelineError(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
@@ -766,6 +771,7 @@ func TestV02_DoMercuryRequestV02_OneFeedSuccessOneFeedPipelineError(t *testing.T
}
func TestV02_DoMercuryRequestV02_OneFeedSuccessOneFeedErrCode(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
@@ -813,6 +819,7 @@ func TestV02_DoMercuryRequestV02_OneFeedSuccessOneFeedErrCode(t *testing.T) {
}
func TestV02_DoMercuryRequestV02_OneFeedSuccessOneFeedPipelineErrorConvertedError(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v03/v03_request_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v03/v03_request_test.go
index 9c0e2aaa147..be99296d153 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v03/v03_request_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/v03/v03_request_test.go
@@ -99,6 +99,7 @@ func setupClient(t *testing.T) *client {
}
func TestV03_DoMercuryRequestV03(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
tests := []struct {
@@ -179,6 +180,7 @@ func TestV03_DoMercuryRequestV03(t *testing.T) {
}
func TestV03_DoMercuryRequestV03_MultipleFeedsSuccess(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
@@ -230,6 +232,7 @@ func TestV03_DoMercuryRequestV03_MultipleFeedsSuccess(t *testing.T) {
}
func TestV03_DoMercuryRequestV03_Timeout(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
@@ -286,6 +289,7 @@ func TestV03_DoMercuryRequestV03_Timeout(t *testing.T) {
}
func TestV03_DoMercuryRequestV03_OneFeedSuccessOneFeedPipelineError(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
@@ -342,6 +346,7 @@ func TestV03_DoMercuryRequestV03_OneFeedSuccessOneFeedPipelineError(t *testing.T
}
func TestV03_DoMercuryRequestV03_OneFeedSuccessOneFeedErrCode(t *testing.T) {
+ t.Parallel()
upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
pluginRetryKey := "88786950015966611018675766524283132478093844178961698330929478019253453382042|34"
@@ -412,6 +417,7 @@ func TestV03_DoMercuryRequestV03_OneFeedSuccessOneFeedErrCode(t *testing.T) {
}
func TestV03_MultiFeedRequest(t *testing.T) {
+ t.Parallel()
upkeepId := big.NewInt(123456789)
tests := []struct {
name string
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/orm.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/orm.go
index a5bd738de4c..3d8a30f81cd 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/orm.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/orm.go
@@ -1,20 +1,19 @@
package upkeepstate
import (
+ "context"
"math/big"
"time"
- "github.com/jmoiron/sqlx"
"github.com/lib/pq"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
type orm struct {
chainID *ubig.Big
- q pg.Q
+ ds sqlutil.DataSource
}
type persistedStateRecord struct {
@@ -27,17 +26,15 @@ type persistedStateRecord struct {
}
// NewORM creates an ORM scoped to chainID.
-func NewORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *orm {
+func NewORM(chainID *big.Int, ds sqlutil.DataSource) *orm {
return &orm{
chainID: ubig.New(chainID),
- q: pg.NewQ(db, lggr.Named("ORM"), cfg),
+ ds: ds,
}
}
// BatchInsertRecords is idempotent and sets upkeep state values in db
-func (o *orm) BatchInsertRecords(state []persistedStateRecord, qopts ...pg.QOpt) error {
- q := o.q.WithOpts(qopts...)
-
+func (o *orm) BatchInsertRecords(ctx context.Context, state []persistedStateRecord) error {
if len(state) == 0 {
return nil
}
@@ -65,17 +62,16 @@ func (o *orm) BatchInsertRecords(state []persistedStateRecord, qopts ...pg.QOpt)
})
}
- return q.ExecQNamed(`INSERT INTO evm.upkeep_states
+ _, err := o.ds.NamedExecContext(ctx, `INSERT INTO evm.upkeep_states
(evm_chain_id, work_id, completion_state, block_number, inserted_at, upkeep_id, ineligibility_reason) VALUES
(:evm_chain_id, :work_id, :completion_state, :block_number, :inserted_at, :upkeep_id, :ineligibility_reason) ON CONFLICT (evm_chain_id, work_id) DO NOTHING`, rows)
+ return err
}
// SelectStatesByWorkIDs searches the data store for stored states for the
// provided work ids and configured chain id
-func (o *orm) SelectStatesByWorkIDs(workIDs []string, qopts ...pg.QOpt) (states []persistedStateRecord, err error) {
- q := o.q.WithOpts(qopts...)
-
- err = q.Select(&states, `SELECT upkeep_id, work_id, completion_state, block_number, ineligibility_reason, inserted_at
+func (o *orm) SelectStatesByWorkIDs(ctx context.Context, workIDs []string) (states []persistedStateRecord, err error) {
+ err = o.ds.SelectContext(ctx, &states, `SELECT upkeep_id, work_id, completion_state, block_number, ineligibility_reason, inserted_at
FROM evm.upkeep_states
WHERE work_id = ANY($1) AND evm_chain_id = $2::NUMERIC`, pq.Array(workIDs), o.chainID)
@@ -87,9 +83,8 @@ func (o *orm) SelectStatesByWorkIDs(workIDs []string, qopts ...pg.QOpt) (states
}
// DeleteExpired prunes stored states older than to the provided time
-func (o *orm) DeleteExpired(expired time.Time, qopts ...pg.QOpt) error {
- q := o.q.WithOpts(qopts...)
- _, err := q.Exec(`DELETE FROM evm.upkeep_states WHERE inserted_at <= $1 AND evm_chain_id::NUMERIC = $2`, expired, o.chainID)
+func (o *orm) DeleteExpired(ctx context.Context, expired time.Time) error {
+ _, err := o.ds.ExecContext(ctx, `DELETE FROM evm.upkeep_states WHERE inserted_at <= $1 AND evm_chain_id::NUMERIC = $2`, expired, o.chainID)
return err
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/orm_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/orm_test.go
index bfd131b5055..894e3b0ef33 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/orm_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/orm_test.go
@@ -7,19 +7,17 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "go.uber.org/zap/zapcore"
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 TestInsertSelectDelete(t *testing.T) {
- lggr, _ := logger.TestLoggerObserved(t, zapcore.ErrorLevel)
+ ctx := testutils.Context(t)
chainID := testutils.FixtureChainID
db := pgtest.NewSqlxDB(t)
- orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(chainID, db)
inserted := []persistedStateRecord{
{
@@ -32,20 +30,20 @@ func TestInsertSelectDelete(t *testing.T) {
},
}
- err := orm.BatchInsertRecords(inserted)
+ err := orm.BatchInsertRecords(ctx, inserted)
require.NoError(t, err, "no error expected from insert")
- states, err := orm.SelectStatesByWorkIDs([]string{"0x1"})
+ states, err := orm.SelectStatesByWorkIDs(ctx, []string{"0x1"})
require.NoError(t, err, "no error expected from select")
require.Len(t, states, 1, "records return should equal records inserted")
- err = orm.DeleteExpired(time.Now())
+ err = orm.DeleteExpired(ctx, time.Now())
assert.NoError(t, err, "no error expected from delete")
- states, err = orm.SelectStatesByWorkIDs([]string{"0x1"})
+ states, err = orm.SelectStatesByWorkIDs(ctx, []string{"0x1"})
require.NoError(t, err, "no error expected from select")
require.Len(t, states, 0, "records return should be empty since records were deleted")
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store.go
index 9410374d7ca..bf7a62aad48 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store.go
@@ -8,6 +8,7 @@ import (
"sync"
"time"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
ocr2keepers "github.com/smartcontractkit/chainlink-common/pkg/types/automation"
"github.com/smartcontractkit/chainlink-common/pkg/services"
@@ -15,7 +16,6 @@ import (
ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -31,9 +31,9 @@ const (
)
type ORM interface {
- BatchInsertRecords([]persistedStateRecord, ...pg.QOpt) error
- SelectStatesByWorkIDs([]string, ...pg.QOpt) ([]persistedStateRecord, error)
- DeleteExpired(time.Time, ...pg.QOpt) error
+ BatchInsertRecords(context.Context, []persistedStateRecord) error
+ SelectStatesByWorkIDs(context.Context, []string) ([]persistedStateRecord, error)
+ DeleteExpired(context.Context, time.Time) error
}
// UpkeepStateStore is the interface for managing upkeeps final state in a local store.
@@ -152,7 +152,7 @@ func (u *upkeepStateStore) flush(ctx context.Context) {
u.sem <- struct{}{}
go func() {
- if err := u.orm.BatchInsertRecords(batch, pg.WithParentCtx(ctx)); err != nil {
+ if err := u.orm.BatchInsertRecords(ctx, batch); err != nil {
u.lggr.Errorw("error inserting records", "err", err)
}
<-u.sem
@@ -268,7 +268,7 @@ func (u *upkeepStateStore) fetchPerformed(ctx context.Context, workIDs ...string
// fetchFromDB fetches all upkeeps indicated as ineligible from the db to
// populate the cache.
func (u *upkeepStateStore) fetchFromDB(ctx context.Context, workIDs ...string) error {
- states, err := u.orm.SelectStatesByWorkIDs(workIDs, pg.WithParentCtx(ctx))
+ states, err := u.orm.SelectStatesByWorkIDs(ctx, workIDs)
if err != nil {
return err
}
@@ -320,7 +320,9 @@ func (u *upkeepStateStore) cleanup(ctx context.Context) error {
func (u *upkeepStateStore) cleanDB(ctx context.Context) error {
tm := time.Now().Add(-1 * u.retention)
- return u.orm.DeleteExpired(tm, pg.WithParentCtx(ctx), pg.WithLongQueryTimeout())
+ ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute)
+ defer cancel()
+ return u.orm.DeleteExpired(ctx, tm)
}
// cleanupCache removes any records from the cache that are older than the TTL.
diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store_test.go
index 3912e2a99c6..eae92aeca35 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/store_test.go
@@ -18,7 +18,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
func TestUpkeepStateStore(t *testing.T) {
@@ -329,20 +328,16 @@ func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) {
lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.ErrorLevel)
chainID := testutils.FixtureChainID
db := pgtest.NewSqlxDB(t)
- realORM := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
+ realORM := NewORM(chainID, db)
insertFinished := make(chan struct{}, 1)
orm := &wrappedORM{
- BatchInsertRecordsFn: func(records []persistedStateRecord, opt ...pg.QOpt) error {
- err := realORM.BatchInsertRecords(records, opt...)
+ BatchInsertRecordsFn: func(ctx context.Context, records []persistedStateRecord) error {
+ err := realORM.BatchInsertRecords(ctx, records)
insertFinished <- struct{}{}
return err
},
- SelectStatesByWorkIDsFn: func(strings []string, opt ...pg.QOpt) ([]persistedStateRecord, error) {
- return realORM.SelectStatesByWorkIDs(strings, opt...)
- },
- DeleteExpiredFn: func(t time.Time, opt ...pg.QOpt) error {
- return realORM.DeleteExpired(t, opt...)
- },
+ SelectStatesByWorkIDsFn: realORM.SelectStatesByWorkIDs,
+ DeleteExpiredFn: realORM.DeleteExpired,
}
scanner := &mockScanner{}
store := NewUpkeepStateStore(orm, lggr, scanner)
@@ -389,20 +384,16 @@ func TestUpkeepStateStore_emptyDB(t *testing.T) {
lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.ErrorLevel)
chainID := testutils.FixtureChainID
db := pgtest.NewSqlxDB(t)
- realORM := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
+ realORM := NewORM(chainID, db)
insertFinished := make(chan struct{}, 1)
orm := &wrappedORM{
- BatchInsertRecordsFn: func(records []persistedStateRecord, opt ...pg.QOpt) error {
- err := realORM.BatchInsertRecords(records, opt...)
+ BatchInsertRecordsFn: func(ctx context.Context, records []persistedStateRecord) error {
+ err := realORM.BatchInsertRecords(ctx, records)
insertFinished <- struct{}{}
return err
},
- SelectStatesByWorkIDsFn: func(strings []string, opt ...pg.QOpt) ([]persistedStateRecord, error) {
- return realORM.SelectStatesByWorkIDs(strings, opt...)
- },
- DeleteExpiredFn: func(t time.Time, opt ...pg.QOpt) error {
- return realORM.DeleteExpired(t, opt...)
- },
+ SelectStatesByWorkIDsFn: realORM.SelectStatesByWorkIDs,
+ DeleteExpiredFn: realORM.DeleteExpired,
}
scanner := &mockScanner{}
store := NewUpkeepStateStore(orm, lggr, scanner)
@@ -427,7 +418,7 @@ func TestUpkeepStateStore_Upsert(t *testing.T) {
ctx := testutils.Context(t)
lggr := logger.TestLogger(t)
chainID := testutils.FixtureChainID
- orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(chainID, db)
store := NewUpkeepStateStore(orm, lggr, &mockScanner{})
@@ -560,11 +551,11 @@ func (_m *mockORM) setErr(err error) {
_m.err = err
}
-func (_m *mockORM) BatchInsertRecords(state []persistedStateRecord, opts ...pg.QOpt) error {
+func (_m *mockORM) BatchInsertRecords(ctx context.Context, state []persistedStateRecord) error {
return nil
}
-func (_m *mockORM) SelectStatesByWorkIDs(workIDs []string, opts ...pg.QOpt) ([]persistedStateRecord, error) {
+func (_m *mockORM) SelectStatesByWorkIDs(ctx context.Context, workIDs []string) ([]persistedStateRecord, error) {
_m.lock.Lock()
defer _m.lock.Unlock()
@@ -574,7 +565,7 @@ func (_m *mockORM) SelectStatesByWorkIDs(workIDs []string, opts ...pg.QOpt) ([]p
return res, _m.err
}
-func (_m *mockORM) DeleteExpired(tm time.Time, opts ...pg.QOpt) error {
+func (_m *mockORM) DeleteExpired(ctx context.Context, tm time.Time) error {
_m.lock.Lock()
defer _m.lock.Unlock()
@@ -585,19 +576,19 @@ func (_m *mockORM) DeleteExpired(tm time.Time, opts ...pg.QOpt) error {
}
type wrappedORM struct {
- BatchInsertRecordsFn func([]persistedStateRecord, ...pg.QOpt) error
- SelectStatesByWorkIDsFn func([]string, ...pg.QOpt) ([]persistedStateRecord, error)
- DeleteExpiredFn func(time.Time, ...pg.QOpt) error
+ BatchInsertRecordsFn func(context.Context, []persistedStateRecord) error
+ SelectStatesByWorkIDsFn func(context.Context, []string) ([]persistedStateRecord, error)
+ DeleteExpiredFn func(context.Context, time.Time) error
}
-func (o *wrappedORM) BatchInsertRecords(r []persistedStateRecord, q ...pg.QOpt) error {
- return o.BatchInsertRecordsFn(r, q...)
+func (o *wrappedORM) BatchInsertRecords(ctx context.Context, r []persistedStateRecord) error {
+ return o.BatchInsertRecordsFn(ctx, r)
}
-func (o *wrappedORM) SelectStatesByWorkIDs(ids []string, q ...pg.QOpt) ([]persistedStateRecord, error) {
- return o.SelectStatesByWorkIDsFn(ids, q...)
+func (o *wrappedORM) SelectStatesByWorkIDs(ctx context.Context, ids []string) ([]persistedStateRecord, error) {
+ return o.SelectStatesByWorkIDsFn(ctx, ids)
}
-func (o *wrappedORM) DeleteExpired(t time.Time, q ...pg.QOpt) error {
- return o.DeleteExpiredFn(t, q...)
+func (o *wrappedORM) DeleteExpired(ctx context.Context, t time.Time) error {
+ return o.DeleteExpiredFn(ctx, t)
}
diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go
index e7688556124..4adede8d121 100644
--- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go
+++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go
@@ -28,13 +28,13 @@ import (
"github.com/smartcontractkit/chainlink-vrf/dkg"
ocr2vrftypes "github.com/smartcontractkit/chainlink-vrf/types"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
+ vrf_wrapper "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
+ dkg_wrapper "github.com/smartcontractkit/chainlink-vrf/gethwrappers/dkg"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
- dkg_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
- vrf_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
ocr2vrfconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/config"
diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go
index beee01eaf7a..1e21227a11e 100644
--- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go
+++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go
@@ -29,12 +29,12 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mathutil"
+ dkg_wrapper "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
lp_mocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
- dkg_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_beacon.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_beacon.go
index 57521566a71..827b5ae9836 100644
--- a/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_beacon.go
+++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_beacon.go
@@ -16,7 +16,7 @@ import (
types "github.com/ethereum/go-ethereum/core/types"
- vrf_beacon "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
+ vrf_beacon "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
)
// VRFBeaconInterface is an autogenerated mock type for the VRFBeaconInterface type
diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_coordinator.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_coordinator.go
index 4b2155bb4e2..f59d048febe 100644
--- a/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_coordinator.go
+++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_coordinator.go
@@ -16,7 +16,7 @@ import (
types "github.com/ethereum/go-ethereum/core/types"
- vrf_coordinator "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
+ vrf_coordinator "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
)
// VRFCoordinatorInterface is an autogenerated mock type for the VRFCoordinatorInterface type
diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/router.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/router.go
index 77384a085ab..dd7fd5e1ec2 100644
--- a/core/services/ocr2/plugins/ocr2vrf/coordinator/router.go
+++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/router.go
@@ -8,10 +8,10 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
"github.com/smartcontractkit/chainlink/v2/core/logger"
)
diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/router_test.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/router_test.go
index 7135fa862e3..c65dcb15a8f 100644
--- a/core/services/ocr2/plugins/ocr2vrf/coordinator/router_test.go
+++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/router_test.go
@@ -9,8 +9,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks"
)
diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/topics.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/topics.go
index 370f0c5fd00..f8fae150c06 100644
--- a/core/services/ocr2/plugins/ocr2vrf/coordinator/topics.go
+++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/topics.go
@@ -3,8 +3,8 @@ package coordinator
import (
"github.com/ethereum/go-ethereum/common"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
)
type topics struct {
diff --git a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go
index 769bffd584f..94c4c0bb8fc 100644
--- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go
+++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go
@@ -32,6 +32,11 @@ import (
commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils"
+ dkg_wrapper "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/load_test_beacon_consumer"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon"
+ "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon_consumer"
+ vrf_wrapper "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
@@ -39,11 +44,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract"
- dkg_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer"
- vrf_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
diff --git a/core/services/ocr2/plugins/s4/integration_test.go b/core/services/ocr2/plugins/s4/integration_test.go
index 8efe38f8e2d..5148ea6e26d 100644
--- a/core/services/ocr2/plugins/s4/integration_test.go
+++ b/core/services/ocr2/plugins/s4/integration_test.go
@@ -15,7 +15,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/s4"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
s4_svc "github.com/smartcontractkit/chainlink/v2/core/services/s4"
commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger"
@@ -53,7 +52,7 @@ func newDON(t *testing.T, size int, config *s4.PluginConfig) *don {
for i := 0; i < size; i++ {
ns := fmt.Sprintf("s4_int_test_%d", i)
- orm := s4_svc.NewPostgresORM(db, logger, pgtest.NewQConfig(false), s4_svc.SharedTableName, ns)
+ orm := s4_svc.NewPostgresORM(db, s4_svc.SharedTableName, ns)
orms[i] = orm
ocrLogger := commonlogger.NewOCRWrapper(logger, true, func(msg string) {})
@@ -149,7 +148,7 @@ func checkNoErrors(t *testing.T, errors []error) {
func checkNoUnconfirmedRows(ctx context.Context, t *testing.T, orm s4_svc.ORM, limit uint) {
t.Helper()
- rows, err := orm.GetUnconfirmedRows(limit, pg.WithParentCtx(ctx))
+ rows, err := orm.GetUnconfirmedRows(ctx, limit)
assert.NoError(t, err)
assert.Empty(t, rows)
}
@@ -161,10 +160,10 @@ func TestS4Integration_HappyDON(t *testing.T) {
// injecting new records
rows := generateTestOrmRows(t, 10, time.Minute)
for _, row := range rows {
- err := don.orms[0].Update(row, pg.WithParentCtx(ctx))
+ err := don.orms[0].Update(ctx, row)
require.NoError(t, err)
}
- originSnapshot, err := don.orms[0].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ originSnapshot, err := don.orms[0].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
// S4 to propagate all records in one OCR round
@@ -172,7 +171,7 @@ func TestS4Integration_HappyDON(t *testing.T) {
checkNoErrors(t, errors)
for i := 0; i < don.size; i++ {
- snapshot, err := don.orms[i].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ snapshot, err := don.orms[i].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
equal := compareSnapshots(originSnapshot, snapshot)
assert.True(t, equal, "oracle %d", i)
@@ -188,7 +187,7 @@ func TestS4Integration_HappyDON_4X(t *testing.T) {
for o := 0; o < don.size; o++ {
rows := generateTestOrmRows(t, 10, time.Minute)
for _, row := range rows {
- err := don.orms[o].Update(row, pg.WithParentCtx(ctx))
+ err := don.orms[o].Update(ctx, row)
require.NoError(t, err)
}
}
@@ -197,11 +196,11 @@ func TestS4Integration_HappyDON_4X(t *testing.T) {
errors := don.simulateOCR(ctx, 1)
checkNoErrors(t, errors)
- firstSnapshot, err := don.orms[0].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ firstSnapshot, err := don.orms[0].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
for i := 1; i < don.size; i++ {
- snapshot, err := don.orms[i].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ snapshot, err := don.orms[i].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
equal := compareSnapshots(firstSnapshot, snapshot)
assert.True(t, equal, "oracle %d", i)
@@ -217,10 +216,10 @@ func TestS4Integration_WrongSignature(t *testing.T) {
rows := generateTestOrmRows(t, 10, time.Minute)
rows[0].Signature = rows[1].Signature
for _, row := range rows {
- err := don.orms[0].Update(row, pg.WithParentCtx(ctx))
+ err := don.orms[0].Update(ctx, row)
require.NoError(t, err)
}
- originSnapshot, err := don.orms[0].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ originSnapshot, err := don.orms[0].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
originSnapshot = filter(originSnapshot, func(row *s4_svc.SnapshotRow) bool {
return row.Address.Cmp(rows[0].Address) != 0 || row.SlotId != rows[0].SlotId
@@ -232,14 +231,14 @@ func TestS4Integration_WrongSignature(t *testing.T) {
checkNoErrors(t, errors)
for i := 1; i < don.size; i++ {
- snapshot, err2 := don.orms[i].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ snapshot, err2 := don.orms[i].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err2)
equal := compareSnapshots(originSnapshot, snapshot)
assert.True(t, equal, "oracle %d", i)
}
// record with a wrong signature must remain unconfirmed
- ur, err := don.orms[0].GetUnconfirmedRows(10, pg.WithParentCtx(ctx))
+ ur, err := don.orms[0].GetUnconfirmedRows(ctx, 10)
require.NoError(t, err)
require.Len(t, ur, 1)
}
@@ -253,10 +252,10 @@ func TestS4Integration_MaxObservations(t *testing.T) {
// injecting new records
rows := generateTestOrmRows(t, 10, time.Minute)
for _, row := range rows {
- err := don.orms[0].Update(row, pg.WithParentCtx(ctx))
+ err := don.orms[0].Update(ctx, row)
require.NoError(t, err)
}
- originSnapshot, err := don.orms[0].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ originSnapshot, err := don.orms[0].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
// It requires at least two rounds due to MaxObservationEntries = rows / 2
@@ -264,7 +263,7 @@ func TestS4Integration_MaxObservations(t *testing.T) {
checkNoErrors(t, errors)
for i := 1; i < don.size; i++ {
- snapshot, err := don.orms[i].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ snapshot, err := don.orms[i].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
equal := compareSnapshots(originSnapshot, snapshot)
assert.True(t, equal, "oracle %d", i)
@@ -280,7 +279,7 @@ func TestS4Integration_Expired(t *testing.T) {
// injecting expiring records
rows := generateTestOrmRows(t, 10, time.Millisecond)
for _, row := range rows {
- err := don.orms[0].Update(row, pg.WithParentCtx(ctx))
+ err := don.orms[0].Update(ctx, row)
require.NoError(t, err)
}
@@ -290,7 +289,7 @@ func TestS4Integration_Expired(t *testing.T) {
checkNoErrors(t, errors)
for i := 0; i < don.size; i++ {
- snapshot, err := don.orms[i].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ snapshot, err := don.orms[i].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
require.Len(t, snapshot, 0)
}
@@ -305,10 +304,10 @@ func TestS4Integration_NSnapshotShards(t *testing.T) {
// injecting lots of new records (to be close to normal address distribution)
rows := generateTestOrmRows(t, 1000, time.Minute)
for _, row := range rows {
- err := don.orms[0].Update(row, pg.WithParentCtx(ctx))
+ err := don.orms[0].Update(ctx, row)
require.NoError(t, err)
}
- originSnapshot, err := don.orms[0].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ originSnapshot, err := don.orms[0].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
// this still requires one round, because Observation takes all unconfirmed rows
@@ -316,7 +315,7 @@ func TestS4Integration_NSnapshotShards(t *testing.T) {
checkNoErrors(t, errors)
for i := 1; i < don.size; i++ {
- snapshot, err := don.orms[i].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ snapshot, err := don.orms[i].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
equal := compareSnapshots(originSnapshot, snapshot)
assert.True(t, equal, "oracle %d", i)
@@ -332,7 +331,7 @@ func TestS4Integration_OneNodeOutOfSync(t *testing.T) {
rows := generateConfirmedTestOrmRows(t, 10, time.Minute)
for o := 0; o < don.size-1; o++ {
for _, row := range rows {
- err := don.orms[o].Update(row, pg.WithParentCtx(ctx))
+ err := don.orms[o].Update(ctx, row)
require.NoError(t, err)
}
}
@@ -342,9 +341,9 @@ func TestS4Integration_OneNodeOutOfSync(t *testing.T) {
errors := don.simulateOCR(ctx, 4)
checkNoErrors(t, errors)
- firstSnapshot, err := don.orms[0].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ firstSnapshot, err := don.orms[0].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
- lastSnapshot, err := don.orms[don.size-1].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ lastSnapshot, err := don.orms[don.size-1].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
equal := compareSnapshots(firstSnapshot, lastSnapshot)
assert.True(t, equal)
@@ -389,7 +388,7 @@ func TestS4Integration_RandomState(t *testing.T) {
sig, err := env.Sign(user.privateKey)
require.NoError(t, err)
row.Signature = sig
- err = don.orms[o].Update(row, pg.WithParentCtx(ctx))
+ err = don.orms[o].Update(ctx, row)
require.NoError(t, err)
}
}
@@ -398,13 +397,13 @@ func TestS4Integration_RandomState(t *testing.T) {
errors := don.simulateOCR(ctx, 4)
checkNoErrors(t, errors)
- firstSnapshot, err := don.orms[0].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ firstSnapshot, err := don.orms[0].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
require.NotEmpty(t, firstSnapshot)
checkNoUnconfirmedRows(ctx, t, don.orms[0], 1000)
for i := 1; i < don.size; i++ {
- snapshot, err := don.orms[i].GetSnapshot(s4_svc.NewFullAddressRange(), pg.WithParentCtx(ctx))
+ snapshot, err := don.orms[i].GetSnapshot(ctx, s4_svc.NewFullAddressRange())
require.NoError(t, err)
equal := compareSnapshots(firstSnapshot, snapshot)
assert.True(t, equal, "oracle %d", i)
diff --git a/core/services/ocr2/plugins/s4/plugin.go b/core/services/ocr2/plugins/s4/plugin.go
index 2b55ebf3cc5..6976c606045 100644
--- a/core/services/ocr2/plugins/s4/plugin.go
+++ b/core/services/ocr2/plugins/s4/plugin.go
@@ -12,7 +12,6 @@ import (
"github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/s4"
)
@@ -69,7 +68,7 @@ func NewReportingPlugin(logger commontypes.Logger, config *PluginConfig, orm s4.
func (c *plugin) Query(ctx context.Context, ts types.ReportTimestamp) (types.Query, error) {
promReportingPluginQuery.WithLabelValues(c.config.ProductName).Inc()
- snapshot, err := c.orm.GetSnapshot(c.addressRange, pg.WithParentCtx(ctx))
+ snapshot, err := c.orm.GetSnapshot(ctx, c.addressRange)
if err != nil {
return nil, errors.Wrap(err, "failed to GetVersions in Query()")
}
@@ -111,7 +110,7 @@ func (c *plugin) Observation(ctx context.Context, ts types.ReportTimestamp, quer
promReportingPluginObservation.WithLabelValues(c.config.ProductName).Inc()
now := time.Now().UTC()
- count, err := c.orm.DeleteExpired(c.config.MaxDeleteExpiredEntries, now, pg.WithParentCtx(ctx))
+ count, err := c.orm.DeleteExpired(ctx, c.config.MaxDeleteExpiredEntries, now)
if err != nil {
return nil, errors.Wrap(err, "failed to DeleteExpired in Observation()")
}
@@ -122,7 +121,7 @@ func (c *plugin) Observation(ctx context.Context, ts types.ReportTimestamp, quer
return MarshalRows(convertRows(rows))
}
- unconfirmedRows, err := c.orm.GetUnconfirmedRows(c.config.MaxObservationEntries, pg.WithParentCtx(ctx))
+ unconfirmedRows, err := c.orm.GetUnconfirmedRows(ctx, c.config.MaxObservationEntries)
if err != nil {
return nil, errors.Wrap(err, "failed to GetUnconfirmedRows in Observation()")
}
@@ -138,7 +137,7 @@ func (c *plugin) Observation(ctx context.Context, ts types.ReportTimestamp, quer
if err != nil {
c.logger.Error("Failed to unmarshal query (likely malformed)", commontypes.LogFields{"err": err})
} else {
- snapshot, err := c.orm.GetSnapshot(addressRange, pg.WithParentCtx(ctx))
+ snapshot, err := c.orm.GetSnapshot(ctx, addressRange)
if err != nil {
c.logger.Error("ORM GetSnapshot error", commontypes.LogFields{"err": err})
} else {
@@ -178,7 +177,7 @@ func (c *plugin) Observation(ctx context.Context, ts types.ReportTimestamp, quer
}
for _, k := range toBeAdded {
- row, err := c.orm.Get(k.address, k.slotID, pg.WithParentCtx(ctx))
+ row, err := c.orm.Get(ctx, k.address, k.slotID)
if err == nil {
remainingRows = append(remainingRows, row)
} else if !errors.Is(err, s4.ErrNotFound) {
@@ -283,7 +282,7 @@ func (c *plugin) ShouldAcceptFinalizedReport(ctx context.Context, ts types.Repor
continue
}
- err = c.orm.Update(ormRow, pg.WithParentCtx(ctx))
+ err = c.orm.Update(ctx, ormRow)
if err != nil && !errors.Is(err, s4.ErrVersionTooLow) {
c.logger.Error("Failed to Update a row in ShouldAcceptFinalizedReport()", commontypes.LogFields{"err": err})
continue
diff --git a/core/services/ocr2/plugins/s4/plugin_test.go b/core/services/ocr2/plugins/s4/plugin_test.go
index b53ab40bfcb..6321b8ce867 100644
--- a/core/services/ocr2/plugins/s4/plugin_test.go
+++ b/core/services/ocr2/plugins/s4/plugin_test.go
@@ -205,7 +205,7 @@ func TestPlugin_ShouldAcceptFinalizedReport(t *testing.T) {
ormRows := make([]*s4_svc.Row, 0)
rows := generateTestRows(t, 10, time.Minute)
orm.On("Update", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
- updateRow := args.Get(0).(*s4_svc.Row)
+ updateRow := args.Get(1).(*s4_svc.Row)
ormRows = append(ormRows, updateRow)
}).Return(nil).Times(10)
@@ -344,8 +344,8 @@ func TestPlugin_Observation(t *testing.T) {
for _, or := range ormRows {
or.Confirmed = false
}
- orm.On("DeleteExpired", uint(10), mock.Anything, mock.Anything).Return(int64(10), nil).Once()
- orm.On("GetUnconfirmedRows", config.MaxObservationEntries, mock.Anything).Return(ormRows, nil).Once()
+ orm.On("DeleteExpired", mock.Anything, uint(10), mock.Anything, mock.Anything).Return(int64(10), nil).Once()
+ orm.On("GetUnconfirmedRows", mock.Anything, config.MaxObservationEntries).Return(ormRows, nil).Once()
observation, err := plugin.Observation(testutils.Context(t), types.ReportTimestamp{}, []byte{})
assert.NoError(t, err)
@@ -370,8 +370,8 @@ func TestPlugin_Observation(t *testing.T) {
Confirmed: or.Confirmed,
}
}
- orm.On("DeleteExpired", uint(10), mock.Anything, mock.Anything).Return(int64(10), nil).Once()
- orm.On("GetUnconfirmedRows", config.MaxObservationEntries, mock.Anything).Return(ormRows[numUnconfirmed:], nil).Once()
+ orm.On("DeleteExpired", mock.Anything, uint(10), mock.Anything, mock.Anything).Return(int64(10), nil).Once()
+ orm.On("GetUnconfirmedRows", mock.Anything, config.MaxObservationEntries).Return(ormRows[numUnconfirmed:], nil).Once()
orm.On("GetSnapshot", mock.Anything, mock.Anything).Return(snapshot, nil).Once()
snapshotRows := rowsToShapshotRows(ormRows)
@@ -388,7 +388,7 @@ func TestPlugin_Observation(t *testing.T) {
if i < numHigherVersion {
ormRows[i].Version++
snapshot[i].Version++
- orm.On("Get", v.Address, v.SlotId, mock.Anything).Return(ormRows[i], nil).Once()
+ orm.On("Get", mock.Anything, v.Address, v.SlotId).Return(ormRows[i], nil).Once()
}
}
queryBytes, err := proto.Marshal(query)
@@ -447,11 +447,11 @@ func TestPlugin_Observation(t *testing.T) {
queryBytes, err := proto.Marshal(query)
assert.NoError(t, err)
- orm.On("DeleteExpired", uint(10), mock.Anything, mock.Anything).Return(int64(10), nil).Once()
- orm.On("GetUnconfirmedRows", config.MaxObservationEntries, mock.Anything).Return([]*s4_svc.Row{}, nil).Once()
+ orm.On("DeleteExpired", mock.Anything, uint(10), mock.Anything, mock.Anything).Return(int64(10), nil).Once()
+ orm.On("GetUnconfirmedRows", mock.Anything, config.MaxObservationEntries).Return([]*s4_svc.Row{}, nil).Once()
orm.On("GetSnapshot", mock.Anything, mock.Anything).Return(snapshot, nil).Once()
- orm.On("Get", snapshot[1].Address, snapshot[1].SlotId, mock.Anything).Return(ormRows[1], nil).Once()
- orm.On("Get", snapshot[2].Address, snapshot[2].SlotId, mock.Anything).Return(ormRows[2], nil).Once()
+ orm.On("Get", mock.Anything, snapshot[1].Address, snapshot[1].SlotId).Return(ormRows[1], nil).Once()
+ orm.On("Get", mock.Anything, snapshot[2].Address, snapshot[2].SlotId).Return(ormRows[2], nil).Once()
observation, err := plugin.Observation(testutils.Context(t), types.ReportTimestamp{}, queryBytes)
assert.NoError(t, err)
diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go
index 9ed7cbea477..2d87cf80346 100644
--- a/core/services/ocrbootstrap/delegate.go
+++ b/core/services/ocrbootstrap/delegate.go
@@ -19,7 +19,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
)
@@ -190,6 +189,6 @@ func (d *Delegate) AfterJobCreated(spec job.Job) {
func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
// OnDeleteJob satisfies the job.Delegate interface.
-func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job, q pg.Queryer) error {
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error {
return nil
}
diff --git a/core/services/ocrcommon/run_saver.go b/core/services/ocrcommon/run_saver.go
index 6d85aa857a4..52ffb31cea0 100644
--- a/core/services/ocrcommon/run_saver.go
+++ b/core/services/ocrcommon/run_saver.go
@@ -2,15 +2,16 @@ package ocrcommon
import (
"context"
+ "time"
"github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
)
type Runner interface {
- InsertFinishedRun(run *pipeline.Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error
+ InsertFinishedRun(ctx context.Context, ds sqlutil.DataSource, run *pipeline.Run, saveSuccessfulTaskRuns bool) error
}
type RunResultSaver struct {
@@ -19,7 +20,7 @@ type RunResultSaver struct {
maxSuccessfulRuns uint64
runResults chan *pipeline.Run
pipelineRunner Runner
- done chan struct{}
+ stopCh services.StopChan
logger logger.Logger
}
@@ -36,7 +37,7 @@ func NewResultRunSaver(pipelineRunner Runner,
maxSuccessfulRuns: maxSuccessfulRuns,
runResults: make(chan *pipeline.Run, resultsWriteDepth),
pipelineRunner: pipelineRunner,
- done: make(chan struct{}),
+ stopCh: make(chan struct{}),
logger: logger.Named("RunResultSaver"),
}
}
@@ -55,6 +56,8 @@ func (r *RunResultSaver) Save(run *pipeline.Run) {
func (r *RunResultSaver) Start(context.Context) error {
return r.StartOnce("RunResultSaver", func() error {
go func() {
+ ctx, cancel := r.stopCh.NewCtx()
+ defer cancel()
for {
select {
case run := <-r.runResults:
@@ -66,10 +69,10 @@ func (r *RunResultSaver) Start(context.Context) error {
r.logger.Tracew("RunSaver: saving job run", "run", run)
// We do not want save successful TaskRuns as OCR runs very frequently so a lot of records
// are produced and the successful TaskRuns do not provide value.
- if err := r.pipelineRunner.InsertFinishedRun(run, false); err != nil {
+ if err := r.pipelineRunner.InsertFinishedRun(ctx, nil, run, false); err != nil {
r.logger.Errorw("error inserting finished results", "err", err)
}
- case <-r.done:
+ case <-r.stopCh:
return
}
}
@@ -80,7 +83,10 @@ func (r *RunResultSaver) Start(context.Context) error {
func (r *RunResultSaver) Close() error {
return r.StopOnce("RunResultSaver", func() error {
- r.done <- struct{}{}
+ close(r.stopCh)
+
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+ defer cancel()
// In the unlikely event that there are remaining runResults to write,
// drain the channel and save them.
@@ -88,7 +94,7 @@ func (r *RunResultSaver) Close() error {
select {
case run := <-r.runResults:
r.logger.Infow("RunSaver: saving job run before exiting", "run", run)
- if err := r.pipelineRunner.InsertFinishedRun(run, false); err != nil {
+ if err := r.pipelineRunner.InsertFinishedRun(ctx, nil, run, false); err != nil {
r.logger.Errorw("error inserting finished results", "err", err)
}
default:
diff --git a/core/services/ocrcommon/run_saver_test.go b/core/services/ocrcommon/run_saver_test.go
index 7bfe60f2a06..a965792ca1f 100644
--- a/core/services/ocrcommon/run_saver_test.go
+++ b/core/services/ocrcommon/run_saver_test.go
@@ -25,7 +25,7 @@ func TestRunSaver(t *testing.T) {
pipelineRunner.On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = int64(d)
+ args.Get(2).(*pipeline.Run).ID = int64(d)
}).
Once()
rs.Save(&pipeline.Run{ID: int64(i)})
diff --git a/core/services/p2p/wrapper/wrapper.go b/core/services/p2p/wrapper/wrapper.go
index fd47c6c2dd2..acb6694b5a3 100644
--- a/core/services/p2p/wrapper/wrapper.go
+++ b/core/services/p2p/wrapper/wrapper.go
@@ -66,7 +66,9 @@ func convertPeerConfig(keystoreP2P keystore.P2P, p2pConfig config.P2P) (p2p.Peer
DeltaDial: p2pConfig.V2().DeltaDial().Duration(),
DiscovererDatabase: discovererDB,
- MetricsRegisterer: prometheus.DefaultRegisterer,
+ // NOTE: this is equivalent to prometheus.DefaultRegisterer, but we need to use a separate
+ // object to avoid conflicts with the OCR registerer
+ MetricsRegisterer: prometheus.NewRegistry(),
}
return peerConfig, nil
diff --git a/core/services/pg/q_test.go b/core/services/pg/q_test.go
index 66258fabff5..81a883789df 100644
--- a/core/services/pg/q_test.go
+++ b/core/services/pg/q_test.go
@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/store/dialects"
)
@@ -59,6 +60,7 @@ func Test_sprintQ(t *testing.T) {
}
func Test_ExecQWithRowsAffected(t *testing.T) {
+ testutils.SkipShortDB(t)
db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String())
require.NoError(t, err)
q := NewQ(db, logger.NullLogger, NewQConfig(false))
diff --git a/core/services/pipeline/helpers_test.go b/core/services/pipeline/helpers_test.go
index 9ee2dc693f2..0bbdef7a7f2 100644
--- a/core/services/pipeline/helpers_test.go
+++ b/core/services/pipeline/helpers_test.go
@@ -5,6 +5,7 @@ import (
"github.com/google/uuid"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
)
@@ -63,3 +64,5 @@ func (t *ETHTxTask) HelperSetDependencies(legacyChains legacyevm.LegacyChainCont
t.specGasLimit = specGasLimit
t.jobType = jobType
}
+
+func (o *orm) Prune(ds sqlutil.DataSource, pipelineSpecID int32) { o.prune(ds, pipelineSpecID) }
diff --git a/core/services/pipeline/mocks/orm.go b/core/services/pipeline/mocks/orm.go
index b06041767a1..fe9aa2823a4 100644
--- a/core/services/pipeline/mocks/orm.go
+++ b/core/services/pipeline/mocks/orm.go
@@ -8,10 +8,10 @@ import (
models "github.com/smartcontractkit/chainlink/v2/core/store/models"
mock "github.com/stretchr/testify/mock"
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
-
pipeline "github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
+ sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
+
time "time"
uuid "github.com/google/uuid"
@@ -40,24 +40,17 @@ func (_m *ORM) Close() error {
return r0
}
-// CreateRun provides a mock function with given fields: run, qopts
-func (_m *ORM) CreateRun(run *pipeline.Run, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, run)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// CreateRun provides a mock function with given fields: ctx, run
+func (_m *ORM) CreateRun(ctx context.Context, run *pipeline.Run) error {
+ ret := _m.Called(ctx, run)
if len(ret) == 0 {
panic("no return value specified for CreateRun")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*pipeline.Run, ...pg.QOpt) error); ok {
- r0 = rf(run, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run) error); ok {
+ r0 = rf(ctx, run)
} else {
r0 = ret.Error(0)
}
@@ -65,16 +58,9 @@ func (_m *ORM) CreateRun(run *pipeline.Run, qopts ...pg.QOpt) error {
return r0
}
-// CreateSpec provides a mock function with given fields: _a0, maxTaskTimeout, qopts
-func (_m *ORM) CreateSpec(_a0 pipeline.Pipeline, maxTaskTimeout models.Interval, qopts ...pg.QOpt) (int32, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, _a0, maxTaskTimeout)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// CreateSpec provides a mock function with given fields: ctx, ds, _a2, maxTaskTimeout
+func (_m *ORM) CreateSpec(ctx context.Context, ds pipeline.CreateDataSource, _a2 pipeline.Pipeline, maxTaskTimeout models.Interval) (int32, error) {
+ ret := _m.Called(ctx, ds, _a2, maxTaskTimeout)
if len(ret) == 0 {
panic("no return value specified for CreateSpec")
@@ -82,17 +68,17 @@ func (_m *ORM) CreateSpec(_a0 pipeline.Pipeline, maxTaskTimeout models.Interval,
var r0 int32
var r1 error
- if rf, ok := ret.Get(0).(func(pipeline.Pipeline, models.Interval, ...pg.QOpt) (int32, error)); ok {
- return rf(_a0, maxTaskTimeout, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, pipeline.CreateDataSource, pipeline.Pipeline, models.Interval) (int32, error)); ok {
+ return rf(ctx, ds, _a2, maxTaskTimeout)
}
- if rf, ok := ret.Get(0).(func(pipeline.Pipeline, models.Interval, ...pg.QOpt) int32); ok {
- r0 = rf(_a0, maxTaskTimeout, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, pipeline.CreateDataSource, pipeline.Pipeline, models.Interval) int32); ok {
+ r0 = rf(ctx, ds, _a2, maxTaskTimeout)
} else {
r0 = ret.Get(0).(int32)
}
- if rf, ok := ret.Get(1).(func(pipeline.Pipeline, models.Interval, ...pg.QOpt) error); ok {
- r1 = rf(_a0, maxTaskTimeout, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, pipeline.CreateDataSource, pipeline.Pipeline, models.Interval) error); ok {
+ r1 = rf(ctx, ds, _a2, maxTaskTimeout)
} else {
r1 = ret.Error(1)
}
@@ -100,17 +86,37 @@ func (_m *ORM) CreateSpec(_a0 pipeline.Pipeline, maxTaskTimeout models.Interval,
return r0, r1
}
-// DeleteRun provides a mock function with given fields: id
-func (_m *ORM) DeleteRun(id int64) error {
- ret := _m.Called(id)
+// DataSource provides a mock function with given fields:
+func (_m *ORM) DataSource() sqlutil.DataSource {
+ ret := _m.Called()
+
+ if len(ret) == 0 {
+ panic("no return value specified for DataSource")
+ }
+
+ var r0 sqlutil.DataSource
+ if rf, ok := ret.Get(0).(func() sqlutil.DataSource); ok {
+ r0 = rf()
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(sqlutil.DataSource)
+ }
+ }
+
+ return r0
+}
+
+// DeleteRun provides a mock function with given fields: ctx, id
+func (_m *ORM) DeleteRun(ctx context.Context, id int64) error {
+ ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for DeleteRun")
}
var r0 error
- if rf, ok := ret.Get(0).(func(int64) error); ok {
- r0 = rf(id)
+ if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
+ r0 = rf(ctx, id)
} else {
r0 = ret.Error(0)
}
@@ -136,9 +142,9 @@ func (_m *ORM) DeleteRunsOlderThan(_a0 context.Context, _a1 time.Duration) error
return r0
}
-// FindRun provides a mock function with given fields: id
-func (_m *ORM) FindRun(id int64) (pipeline.Run, error) {
- ret := _m.Called(id)
+// FindRun provides a mock function with given fields: ctx, id
+func (_m *ORM) FindRun(ctx context.Context, id int64) (pipeline.Run, error) {
+ ret := _m.Called(ctx, id)
if len(ret) == 0 {
panic("no return value specified for FindRun")
@@ -146,17 +152,17 @@ func (_m *ORM) FindRun(id int64) (pipeline.Run, error) {
var r0 pipeline.Run
var r1 error
- if rf, ok := ret.Get(0).(func(int64) (pipeline.Run, error)); ok {
- return rf(id)
+ if rf, ok := ret.Get(0).(func(context.Context, int64) (pipeline.Run, error)); ok {
+ return rf(ctx, id)
}
- if rf, ok := ret.Get(0).(func(int64) pipeline.Run); ok {
- r0 = rf(id)
+ if rf, ok := ret.Get(0).(func(context.Context, int64) pipeline.Run); ok {
+ r0 = rf(ctx, id)
} else {
r0 = ret.Get(0).(pipeline.Run)
}
- if rf, ok := ret.Get(1).(func(int64) error); ok {
- r1 = rf(id)
+ if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
+ r1 = rf(ctx, id)
} else {
r1 = ret.Error(1)
}
@@ -164,9 +170,9 @@ func (_m *ORM) FindRun(id int64) (pipeline.Run, error) {
return r0, r1
}
-// GetAllRuns provides a mock function with given fields:
-func (_m *ORM) GetAllRuns() ([]pipeline.Run, error) {
- ret := _m.Called()
+// GetAllRuns provides a mock function with given fields: ctx
+func (_m *ORM) GetAllRuns(ctx context.Context) ([]pipeline.Run, error) {
+ ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetAllRuns")
@@ -174,19 +180,19 @@ func (_m *ORM) GetAllRuns() ([]pipeline.Run, error) {
var r0 []pipeline.Run
var r1 error
- if rf, ok := ret.Get(0).(func() ([]pipeline.Run, error)); ok {
- return rf()
+ if rf, ok := ret.Get(0).(func(context.Context) ([]pipeline.Run, error)); ok {
+ return rf(ctx)
}
- if rf, ok := ret.Get(0).(func() []pipeline.Run); ok {
- r0 = rf()
+ if rf, ok := ret.Get(0).(func(context.Context) []pipeline.Run); ok {
+ r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]pipeline.Run)
}
}
- if rf, ok := ret.Get(1).(func() error); ok {
- r1 = rf()
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
@@ -194,24 +200,6 @@ func (_m *ORM) GetAllRuns() ([]pipeline.Run, error) {
return r0, r1
}
-// GetQ provides a mock function with given fields:
-func (_m *ORM) GetQ() pg.Q {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for GetQ")
- }
-
- var r0 pg.Q
- if rf, ok := ret.Get(0).(func() pg.Q); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(pg.Q)
- }
-
- return r0
-}
-
// GetUnfinishedRuns provides a mock function with given fields: _a0, _a1, _a2
func (_m *ORM) GetUnfinishedRuns(_a0 context.Context, _a1 time.Time, _a2 func(pipeline.Run) error) error {
ret := _m.Called(_a0, _a1, _a2)
@@ -250,24 +238,17 @@ func (_m *ORM) HealthReport() map[string]error {
return r0
}
-// InsertFinishedRun provides a mock function with given fields: run, saveSuccessfulTaskRuns, qopts
-func (_m *ORM) InsertFinishedRun(run *pipeline.Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, run, saveSuccessfulTaskRuns)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// InsertFinishedRun provides a mock function with given fields: ctx, run, saveSuccessfulTaskRuns
+func (_m *ORM) InsertFinishedRun(ctx context.Context, run *pipeline.Run, saveSuccessfulTaskRuns bool) error {
+ ret := _m.Called(ctx, run, saveSuccessfulTaskRuns)
if len(ret) == 0 {
panic("no return value specified for InsertFinishedRun")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*pipeline.Run, bool, ...pg.QOpt) error); ok {
- r0 = rf(run, saveSuccessfulTaskRuns, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run, bool) error); ok {
+ r0 = rf(ctx, run, saveSuccessfulTaskRuns)
} else {
r0 = ret.Error(0)
}
@@ -275,24 +256,17 @@ func (_m *ORM) InsertFinishedRun(run *pipeline.Run, saveSuccessfulTaskRuns bool,
return r0
}
-// InsertFinishedRunWithSpec provides a mock function with given fields: run, saveSuccessfulTaskRuns, qopts
-func (_m *ORM) InsertFinishedRunWithSpec(run *pipeline.Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, run, saveSuccessfulTaskRuns)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// InsertFinishedRunWithSpec provides a mock function with given fields: ctx, run, saveSuccessfulTaskRuns
+func (_m *ORM) InsertFinishedRunWithSpec(ctx context.Context, run *pipeline.Run, saveSuccessfulTaskRuns bool) error {
+ ret := _m.Called(ctx, run, saveSuccessfulTaskRuns)
if len(ret) == 0 {
panic("no return value specified for InsertFinishedRunWithSpec")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*pipeline.Run, bool, ...pg.QOpt) error); ok {
- r0 = rf(run, saveSuccessfulTaskRuns, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run, bool) error); ok {
+ r0 = rf(ctx, run, saveSuccessfulTaskRuns)
} else {
r0 = ret.Error(0)
}
@@ -300,24 +274,17 @@ func (_m *ORM) InsertFinishedRunWithSpec(run *pipeline.Run, saveSuccessfulTaskRu
return r0
}
-// InsertFinishedRuns provides a mock function with given fields: run, saveSuccessfulTaskRuns, qopts
-func (_m *ORM) InsertFinishedRuns(run []*pipeline.Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, run, saveSuccessfulTaskRuns)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// InsertFinishedRuns provides a mock function with given fields: ctx, run, saveSuccessfulTaskRuns
+func (_m *ORM) InsertFinishedRuns(ctx context.Context, run []*pipeline.Run, saveSuccessfulTaskRuns bool) error {
+ ret := _m.Called(ctx, run, saveSuccessfulTaskRuns)
if len(ret) == 0 {
panic("no return value specified for InsertFinishedRuns")
}
var r0 error
- if rf, ok := ret.Get(0).(func([]*pipeline.Run, bool, ...pg.QOpt) error); ok {
- r0 = rf(run, saveSuccessfulTaskRuns, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, []*pipeline.Run, bool) error); ok {
+ r0 = rf(ctx, run, saveSuccessfulTaskRuns)
} else {
r0 = ret.Error(0)
}
@@ -325,24 +292,17 @@ func (_m *ORM) InsertFinishedRuns(run []*pipeline.Run, saveSuccessfulTaskRuns bo
return r0
}
-// InsertRun provides a mock function with given fields: run, qopts
-func (_m *ORM) InsertRun(run *pipeline.Run, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, run)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// InsertRun provides a mock function with given fields: ctx, run
+func (_m *ORM) InsertRun(ctx context.Context, run *pipeline.Run) error {
+ ret := _m.Called(ctx, run)
if len(ret) == 0 {
panic("no return value specified for InsertRun")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*pipeline.Run, ...pg.QOpt) error); ok {
- r0 = rf(run, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run) error); ok {
+ r0 = rf(ctx, run)
} else {
r0 = ret.Error(0)
}
@@ -404,16 +364,9 @@ func (_m *ORM) Start(_a0 context.Context) error {
return r0
}
-// StoreRun provides a mock function with given fields: run, qopts
-func (_m *ORM) StoreRun(run *pipeline.Run, qopts ...pg.QOpt) (bool, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, run)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// StoreRun provides a mock function with given fields: ctx, run
+func (_m *ORM) StoreRun(ctx context.Context, run *pipeline.Run) (bool, error) {
+ ret := _m.Called(ctx, run)
if len(ret) == 0 {
panic("no return value specified for StoreRun")
@@ -421,17 +374,17 @@ func (_m *ORM) StoreRun(run *pipeline.Run, qopts ...pg.QOpt) (bool, error) {
var r0 bool
var r1 error
- if rf, ok := ret.Get(0).(func(*pipeline.Run, ...pg.QOpt) (bool, error)); ok {
- return rf(run, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run) (bool, error)); ok {
+ return rf(ctx, run)
}
- if rf, ok := ret.Get(0).(func(*pipeline.Run, ...pg.QOpt) bool); ok {
- r0 = rf(run, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run) bool); ok {
+ r0 = rf(ctx, run)
} else {
r0 = ret.Get(0).(bool)
}
- if rf, ok := ret.Get(1).(func(*pipeline.Run, ...pg.QOpt) error); ok {
- r1 = rf(run, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, *pipeline.Run) error); ok {
+ r1 = rf(ctx, run)
} else {
r1 = ret.Error(1)
}
@@ -439,9 +392,27 @@ func (_m *ORM) StoreRun(run *pipeline.Run, qopts ...pg.QOpt) (bool, error) {
return r0, r1
}
-// UpdateTaskRunResult provides a mock function with given fields: taskID, result
-func (_m *ORM) UpdateTaskRunResult(taskID uuid.UUID, result pipeline.Result) (pipeline.Run, bool, error) {
- ret := _m.Called(taskID, result)
+// Transact provides a mock function with given fields: _a0, _a1
+func (_m *ORM) Transact(_a0 context.Context, _a1 func(pipeline.ORM) error) error {
+ ret := _m.Called(_a0, _a1)
+
+ if len(ret) == 0 {
+ panic("no return value specified for Transact")
+ }
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(context.Context, func(pipeline.ORM) error) error); ok {
+ r0 = rf(_a0, _a1)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// UpdateTaskRunResult provides a mock function with given fields: ctx, taskID, result
+func (_m *ORM) UpdateTaskRunResult(ctx context.Context, taskID uuid.UUID, result pipeline.Result) (pipeline.Run, bool, error) {
+ ret := _m.Called(ctx, taskID, result)
if len(ret) == 0 {
panic("no return value specified for UpdateTaskRunResult")
@@ -450,23 +421,23 @@ func (_m *ORM) UpdateTaskRunResult(taskID uuid.UUID, result pipeline.Result) (pi
var r0 pipeline.Run
var r1 bool
var r2 error
- if rf, ok := ret.Get(0).(func(uuid.UUID, pipeline.Result) (pipeline.Run, bool, error)); ok {
- return rf(taskID, result)
+ if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, pipeline.Result) (pipeline.Run, bool, error)); ok {
+ return rf(ctx, taskID, result)
}
- if rf, ok := ret.Get(0).(func(uuid.UUID, pipeline.Result) pipeline.Run); ok {
- r0 = rf(taskID, result)
+ if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, pipeline.Result) pipeline.Run); ok {
+ r0 = rf(ctx, taskID, result)
} else {
r0 = ret.Get(0).(pipeline.Run)
}
- if rf, ok := ret.Get(1).(func(uuid.UUID, pipeline.Result) bool); ok {
- r1 = rf(taskID, result)
+ if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID, pipeline.Result) bool); ok {
+ r1 = rf(ctx, taskID, result)
} else {
r1 = ret.Get(1).(bool)
}
- if rf, ok := ret.Get(2).(func(uuid.UUID, pipeline.Result) error); ok {
- r2 = rf(taskID, result)
+ if rf, ok := ret.Get(2).(func(context.Context, uuid.UUID, pipeline.Result) error); ok {
+ r2 = rf(ctx, taskID, result)
} else {
r2 = ret.Error(2)
}
@@ -474,6 +445,26 @@ func (_m *ORM) UpdateTaskRunResult(taskID uuid.UUID, result pipeline.Result) (pi
return r0, r1, r2
}
+// WithDataSource provides a mock function with given fields: _a0
+func (_m *ORM) WithDataSource(_a0 sqlutil.DataSource) pipeline.ORM {
+ ret := _m.Called(_a0)
+
+ if len(ret) == 0 {
+ panic("no return value specified for WithDataSource")
+ }
+
+ var r0 pipeline.ORM
+ if rf, ok := ret.Get(0).(func(sqlutil.DataSource) pipeline.ORM); ok {
+ r0 = rf(_a0)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(pipeline.ORM)
+ }
+ }
+
+ return r0
+}
+
// NewORM creates a new instance of ORM. 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 NewORM(t interface {
diff --git a/core/services/pipeline/mocks/runner.go b/core/services/pipeline/mocks/runner.go
index 3de2703f0c7..e0378399f58 100644
--- a/core/services/pipeline/mocks/runner.go
+++ b/core/services/pipeline/mocks/runner.go
@@ -8,10 +8,10 @@ import (
logger "github.com/smartcontractkit/chainlink/v2/core/logger"
mock "github.com/stretchr/testify/mock"
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
-
pipeline "github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
+ sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
+
uuid "github.com/google/uuid"
)
@@ -164,24 +164,17 @@ func (_m *Runner) InitializePipeline(spec pipeline.Spec) (*pipeline.Pipeline, er
return r0, r1
}
-// InsertFinishedRun provides a mock function with given fields: run, saveSuccessfulTaskRuns, qopts
-func (_m *Runner) InsertFinishedRun(run *pipeline.Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, run, saveSuccessfulTaskRuns)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// InsertFinishedRun provides a mock function with given fields: ctx, ds, run, saveSuccessfulTaskRuns
+func (_m *Runner) InsertFinishedRun(ctx context.Context, ds sqlutil.DataSource, run *pipeline.Run, saveSuccessfulTaskRuns bool) error {
+ ret := _m.Called(ctx, ds, run, saveSuccessfulTaskRuns)
if len(ret) == 0 {
panic("no return value specified for InsertFinishedRun")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*pipeline.Run, bool, ...pg.QOpt) error); ok {
- r0 = rf(run, saveSuccessfulTaskRuns, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, sqlutil.DataSource, *pipeline.Run, bool) error); ok {
+ r0 = rf(ctx, ds, run, saveSuccessfulTaskRuns)
} else {
r0 = ret.Error(0)
}
@@ -189,24 +182,17 @@ func (_m *Runner) InsertFinishedRun(run *pipeline.Run, saveSuccessfulTaskRuns bo
return r0
}
-// InsertFinishedRuns provides a mock function with given fields: runs, saveSuccessfulTaskRuns, qopts
-func (_m *Runner) InsertFinishedRuns(runs []*pipeline.Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, runs, saveSuccessfulTaskRuns)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// InsertFinishedRuns provides a mock function with given fields: ctx, ds, runs, saveSuccessfulTaskRuns
+func (_m *Runner) InsertFinishedRuns(ctx context.Context, ds sqlutil.DataSource, runs []*pipeline.Run, saveSuccessfulTaskRuns bool) error {
+ ret := _m.Called(ctx, ds, runs, saveSuccessfulTaskRuns)
if len(ret) == 0 {
panic("no return value specified for InsertFinishedRuns")
}
var r0 error
- if rf, ok := ret.Get(0).(func([]*pipeline.Run, bool, ...pg.QOpt) error); ok {
- r0 = rf(runs, saveSuccessfulTaskRuns, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, sqlutil.DataSource, []*pipeline.Run, bool) error); ok {
+ r0 = rf(ctx, ds, runs, saveSuccessfulTaskRuns)
} else {
r0 = ret.Error(0)
}
@@ -255,17 +241,17 @@ func (_m *Runner) Ready() error {
return r0
}
-// ResumeRun provides a mock function with given fields: taskID, value, err
-func (_m *Runner) ResumeRun(taskID uuid.UUID, value interface{}, err error) error {
- ret := _m.Called(taskID, value, err)
+// ResumeRun provides a mock function with given fields: ctx, taskID, value, err
+func (_m *Runner) ResumeRun(ctx context.Context, taskID uuid.UUID, value interface{}, err error) error {
+ ret := _m.Called(ctx, taskID, value, err)
if len(ret) == 0 {
panic("no return value specified for ResumeRun")
}
var r0 error
- if rf, ok := ret.Get(0).(func(uuid.UUID, interface{}, error) error); ok {
- r0 = rf(taskID, value, err)
+ if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, interface{}, error) error); ok {
+ r0 = rf(ctx, taskID, value, err)
} else {
r0 = ret.Error(0)
}
@@ -274,7 +260,7 @@ func (_m *Runner) ResumeRun(taskID uuid.UUID, value interface{}, err error) erro
}
// Run provides a mock function with given fields: ctx, run, l, saveSuccessfulTaskRuns, fn
-func (_m *Runner) Run(ctx context.Context, run *pipeline.Run, l logger.Logger, saveSuccessfulTaskRuns bool, fn func(pg.Queryer) error) (bool, error) {
+func (_m *Runner) Run(ctx context.Context, run *pipeline.Run, l logger.Logger, saveSuccessfulTaskRuns bool, fn func(sqlutil.DataSource) error) (bool, error) {
ret := _m.Called(ctx, run, l, saveSuccessfulTaskRuns, fn)
if len(ret) == 0 {
@@ -283,16 +269,16 @@ func (_m *Runner) Run(ctx context.Context, run *pipeline.Run, l logger.Logger, s
var r0 bool
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run, logger.Logger, bool, func(pg.Queryer) error) (bool, error)); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run, logger.Logger, bool, func(sqlutil.DataSource) error) (bool, error)); ok {
return rf(ctx, run, l, saveSuccessfulTaskRuns, fn)
}
- if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run, logger.Logger, bool, func(pg.Queryer) error) bool); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, *pipeline.Run, logger.Logger, bool, func(sqlutil.DataSource) error) bool); ok {
r0 = rf(ctx, run, l, saveSuccessfulTaskRuns, fn)
} else {
r0 = ret.Get(0).(bool)
}
- if rf, ok := ret.Get(1).(func(context.Context, *pipeline.Run, logger.Logger, bool, func(pg.Queryer) error) error); ok {
+ if rf, ok := ret.Get(1).(func(context.Context, *pipeline.Run, logger.Logger, bool, func(sqlutil.DataSource) error) error); ok {
r1 = rf(ctx, run, l, saveSuccessfulTaskRuns, fn)
} else {
r1 = ret.Error(1)
diff --git a/core/services/pipeline/orm.go b/core/services/pipeline/orm.go
index c32693e4db4..3bebfb8cbad 100644
--- a/core/services/pipeline/orm.go
+++ b/core/services/pipeline/orm.go
@@ -14,6 +14,7 @@ import (
"github.com/jmoiron/sqlx"
"github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
@@ -71,33 +72,42 @@ const KeepersObservationSource = `
encode_check_upkeep_tx -> check_upkeep_tx -> decode_check_upkeep_tx -> calculate_perform_data_len -> perform_data_lessthan_limit -> check_perform_data_limit -> encode_perform_upkeep_tx -> simulate_perform_upkeep_tx -> decode_check_perform_tx -> check_success -> perform_upkeep_tx
`
+type CreateDataSource interface {
+ GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error
+}
+
//go:generate mockery --quiet --name ORM --output ./mocks/ --case=underscore
type ORM interface {
services.Service
- CreateSpec(pipeline Pipeline, maxTaskTimeout models.Interval, qopts ...pg.QOpt) (int32, error)
- CreateRun(run *Run, qopts ...pg.QOpt) (err error)
- InsertRun(run *Run, qopts ...pg.QOpt) error
- DeleteRun(id int64) error
- StoreRun(run *Run, qopts ...pg.QOpt) (restart bool, err error)
- UpdateTaskRunResult(taskID uuid.UUID, result Result) (run Run, start bool, err error)
- InsertFinishedRun(run *Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) (err error)
- InsertFinishedRunWithSpec(run *Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) (err error)
+
+ // ds is optional and to be removed after completing https://smartcontract-it.atlassian.net/browse/BCF-2978
+ CreateSpec(ctx context.Context, ds CreateDataSource, pipeline Pipeline, maxTaskTimeout models.Interval) (int32, error)
+ CreateRun(ctx context.Context, run *Run) (err error)
+ InsertRun(ctx context.Context, run *Run) error
+ DeleteRun(ctx context.Context, id int64) error
+ StoreRun(ctx context.Context, run *Run) (restart bool, err error)
+ UpdateTaskRunResult(ctx context.Context, taskID uuid.UUID, result Result) (run Run, start bool, err error)
+ InsertFinishedRun(ctx context.Context, run *Run, saveSuccessfulTaskRuns bool) (err error)
+ InsertFinishedRunWithSpec(ctx context.Context, run *Run, saveSuccessfulTaskRuns bool) (err error)
// InsertFinishedRuns inserts all the given runs into the database.
// If saveSuccessfulTaskRuns is false, only errored runs are saved.
- InsertFinishedRuns(run []*Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) (err error)
+ InsertFinishedRuns(ctx context.Context, run []*Run, saveSuccessfulTaskRuns bool) (err error)
DeleteRunsOlderThan(context.Context, time.Duration) error
- FindRun(id int64) (Run, error)
- GetAllRuns() ([]Run, error)
+ FindRun(ctx context.Context, id int64) (Run, error)
+ GetAllRuns(ctx context.Context) ([]Run, error)
GetUnfinishedRuns(context.Context, time.Time, func(run Run) error) error
- GetQ() pg.Q
+
+ DataSource() sqlutil.DataSource
+ WithDataSource(sqlutil.DataSource) ORM
+ Transact(context.Context, func(ORM) error) error
}
type orm struct {
services.StateMachine
- q pg.Q
+ ds sqlutil.DataSource
lggr logger.Logger
maxSuccessfulRuns uint64
// jobID => count
@@ -109,17 +119,14 @@ type orm struct {
var _ ORM = (*orm)(nil)
-func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, jobPipelineMaxSuccessfulRuns uint64) *orm {
+func NewORM(ds sqlutil.DataSource, lggr logger.Logger, jobPipelineMaxSuccessfulRuns uint64) *orm {
ctx, cancel := context.WithCancel(context.Background())
return &orm{
- services.StateMachine{},
- pg.NewQ(db, lggr, cfg),
- lggr.Named("PipelineORM"),
- jobPipelineMaxSuccessfulRuns,
- sync.Map{},
- sync.WaitGroup{},
- ctx,
- cancel,
+ ds: ds,
+ lggr: lggr.Named("PipelineORM"),
+ maxSuccessfulRuns: jobPipelineMaxSuccessfulRuns,
+ ctx: ctx,
+ cncl: cancel,
}
}
@@ -152,23 +159,56 @@ func (o *orm) HealthReport() map[string]error {
return map[string]error{o.Name(): o.Healthy()}
}
-func (o *orm) CreateSpec(pipeline Pipeline, maxTaskDuration models.Interval, qopts ...pg.QOpt) (id int32, err error) {
- q := o.q.WithOpts(qopts...)
+func (o *orm) Transact(ctx context.Context, fn func(ORM) error) error {
+ return sqlutil.Transact(ctx, func(tx sqlutil.DataSource) ORM {
+ return o.withDataSource(tx)
+ }, o.ds, nil, func(tx ORM) error {
+ defer func() {
+ if err := tx.Close(); err != nil {
+ o.lggr.Warnw("Error closing temporary transactional ORM", "err", err)
+ }
+ }()
+ return fn(tx)
+ })
+}
+
+func (o *orm) DataSource() sqlutil.DataSource { return o.ds }
+
+func (o *orm) WithDataSource(ds sqlutil.DataSource) ORM { return o.withDataSource(ds) }
+
+func (o *orm) withDataSource(ds sqlutil.DataSource) *orm {
+ ctx, cancel := context.WithCancel(context.Background())
+ return &orm{
+ ds: ds,
+ lggr: o.lggr,
+ maxSuccessfulRuns: o.maxSuccessfulRuns,
+ ctx: ctx,
+ cncl: cancel,
+ }
+}
+
+func (o *orm) transact(ctx context.Context, fn func(*orm) error) error {
+ return sqlutil.Transact(ctx, o.withDataSource, o.ds, nil, fn)
+}
+
+func (o *orm) CreateSpec(ctx context.Context, ds CreateDataSource, pipeline Pipeline, maxTaskDuration models.Interval) (id int32, err error) {
sql := `INSERT INTO pipeline_specs (dot_dag_source, max_task_duration, created_at)
VALUES ($1, $2, NOW())
RETURNING id;`
- err = q.Get(&id, sql, pipeline.Source, maxTaskDuration)
+ if ds == nil {
+ ds = o.ds
+ }
+ err = ds.GetContext(ctx, &id, sql, pipeline.Source, maxTaskDuration)
return id, errors.WithStack(err)
}
-func (o *orm) CreateRun(run *Run, qopts ...pg.QOpt) (err error) {
+func (o *orm) CreateRun(ctx context.Context, run *Run) (err error) {
if run.CreatedAt.IsZero() {
return errors.New("run.CreatedAt must be set")
}
- q := o.q.WithOpts(qopts...)
- err = q.Transaction(func(tx pg.Queryer) error {
- if e := o.InsertRun(run, pg.WithQueryer(tx)); e != nil {
+ err = o.transact(ctx, func(tx *orm) error {
+ if e := tx.InsertRun(ctx, run); e != nil {
return errors.Wrap(e, "error inserting pipeline_run")
}
@@ -182,10 +222,9 @@ func (o *orm) CreateRun(run *Run, qopts ...pg.QOpt) (err error) {
run.PipelineTaskRuns[i].PipelineRunID = run.ID
}
- sql := `
- INSERT INTO pipeline_task_runs (pipeline_run_id, id, type, index, output, error, dot_id, created_at)
+ sql := `INSERT INTO pipeline_task_runs (pipeline_run_id, id, type, index, output, error, dot_id, created_at)
VALUES (:pipeline_run_id, :id, :type, :index, :output, :error, :dot_id, :created_at);`
- _, err = tx.NamedExec(sql, run.PipelineTaskRuns)
+ _, err = tx.ds.NamedExecContext(ctx, sql, run.PipelineTaskRuns)
return err
})
@@ -193,33 +232,34 @@ func (o *orm) CreateRun(run *Run, qopts ...pg.QOpt) (err error) {
}
// InsertRun inserts a run into the database
-func (o *orm) InsertRun(run *Run, qopts ...pg.QOpt) error {
+func (o *orm) InsertRun(ctx context.Context, run *Run) error {
if run.Status() == RunStatusCompleted {
- defer o.Prune(o.q, run.PruningKey)
+ defer o.prune(o.ds, run.PruningKey)
}
- q := o.q.WithOpts(qopts...)
- sql := `INSERT INTO pipeline_runs (pipeline_spec_id, pruning_key, meta, all_errors, fatal_errors, inputs, outputs, created_at, finished_at, state)
+ query, args, err := o.ds.BindNamed(`INSERT INTO pipeline_runs (pipeline_spec_id, pruning_key, meta, all_errors, fatal_errors, inputs, outputs, created_at, finished_at, state)
VALUES (:pipeline_spec_id, :pruning_key, :meta, :all_errors, :fatal_errors, :inputs, :outputs, :created_at, :finished_at, :state)
- RETURNING *;`
- return q.GetNamed(sql, run, run)
+ RETURNING *;`, run)
+ if err != nil {
+ return fmt.Errorf("error binding arg: %w", err)
+ }
+ return o.ds.GetContext(ctx, run, query, args...)
}
// StoreRun will persist a partially executed run before suspending, or finish a run.
// If `restart` is true, then new task run data is available and the run should be resumed immediately.
-func (o *orm) StoreRun(run *Run, qopts ...pg.QOpt) (restart bool, err error) {
- q := o.q.WithOpts(qopts...)
- err = q.Transaction(func(tx pg.Queryer) error {
+func (o *orm) StoreRun(ctx context.Context, run *Run) (restart bool, err error) {
+ err = o.transact(ctx, func(tx *orm) error {
finished := run.FinishedAt.Valid
if !finished {
// Lock the current run. This prevents races with /v2/resume
sql := `SELECT id FROM pipeline_runs WHERE id = $1 FOR UPDATE;`
- if _, err = tx.Exec(sql, run.ID); err != nil {
+ if _, err = tx.ds.ExecContext(ctx, sql, run.ID); err != nil {
return errors.Wrap(err, "StoreRun")
}
taskRuns := []TaskRun{}
// Reload task runs, we want to check for any changes while the run was ongoing
- if err = sqlx.Select(tx, &taskRuns, `SELECT * FROM pipeline_task_runs WHERE pipeline_run_id = $1`, run.ID); err != nil {
+ if err = tx.ds.SelectContext(ctx, &taskRuns, `SELECT * FROM pipeline_task_runs WHERE pipeline_run_id = $1`, run.ID); err != nil {
return errors.Wrap(err, "StoreRun")
}
@@ -246,17 +286,17 @@ func (o *orm) StoreRun(run *Run, qopts ...pg.QOpt) (restart bool, err error) {
// Suspend the run
run.State = RunStatusSuspended
- if _, err = sqlx.NamedExec(tx, `UPDATE pipeline_runs SET state = :state WHERE id = :id`, run); err != nil {
+ if _, err = tx.ds.NamedExecContext(ctx, `UPDATE pipeline_runs SET state = :state WHERE id = :id`, run); err != nil {
return errors.Wrap(err, "StoreRun")
}
} else {
- defer o.Prune(tx, run.PruningKey)
+ defer o.prune(tx.ds, run.PruningKey)
// Simply finish the run, no need to do any sort of locking
if run.Outputs.Val == nil || len(run.FatalErrors)+len(run.AllErrors) == 0 {
return errors.Errorf("run must have both Outputs and Errors, got Outputs: %#v, FatalErrors: %#v, AllErrors: %#v", run.Outputs.Val, run.FatalErrors, run.AllErrors)
}
sql := `UPDATE pipeline_runs SET state = :state, finished_at = :finished_at, all_errors= :all_errors, fatal_errors= :fatal_errors, outputs = :outputs WHERE id = :id`
- if _, err = sqlx.NamedExec(tx, sql, run); err != nil {
+ if _, err = tx.ds.NamedExecContext(ctx, sql, run); err != nil {
return errors.Wrap(err, "StoreRun")
}
}
@@ -272,7 +312,7 @@ func (o *orm) StoreRun(run *Run, qopts ...pg.QOpt) (restart bool, err error) {
// NOTE: can't use Select() to auto scan because we're using NamedQuery,
// sqlx.Named + Select is possible but it's about the same amount of code
var rows *sqlx.Rows
- rows, err = sqlx.NamedQuery(tx, sql, run.PipelineTaskRuns)
+ rows, err = sqlx.NamedQueryContext(ctx, tx.ds, sql, run.PipelineTaskRuns)
if err != nil {
return errors.Wrap(err, "StoreRun")
}
@@ -288,17 +328,17 @@ func (o *orm) StoreRun(run *Run, qopts ...pg.QOpt) (restart bool, err error) {
}
// DeleteRun cleans up a run that failed and is marked failEarly (should leave no trace of the run)
-func (o *orm) DeleteRun(id int64) error {
+func (o *orm) DeleteRun(ctx context.Context, id int64) error {
// NOTE: this will cascade and wipe pipeline_task_runs too
- _, err := o.q.Exec(`DELETE FROM pipeline_runs WHERE id = $1`, id)
+ _, err := o.ds.ExecContext(ctx, `DELETE FROM pipeline_runs WHERE id = $1`, id)
return err
}
-func (o *orm) UpdateTaskRunResult(taskID uuid.UUID, result Result) (run Run, start bool, err error) {
+func (o *orm) UpdateTaskRunResult(ctx context.Context, taskID uuid.UUID, result Result) (run Run, start bool, err error) {
if result.OutputDB().Valid && result.ErrorDB().Valid {
panic("run result must specify either output or error, not both")
}
- err = o.q.Transaction(func(tx pg.Queryer) error {
+ err = o.transact(ctx, func(tx *orm) error {
sql := `
SELECT pipeline_runs.*, pipeline_specs.dot_dag_source "pipeline_spec.dot_dag_source", job_pipeline_specs.job_id "job_id"
FROM pipeline_runs
@@ -307,13 +347,13 @@ func (o *orm) UpdateTaskRunResult(taskID uuid.UUID, result Result) (run Run, sta
JOIN job_pipeline_specs ON (job_pipeline_specs.pipeline_spec_id = pipeline_specs.id)
WHERE pipeline_task_runs.id = $1 AND pipeline_runs.state in ('running', 'suspended')
FOR UPDATE`
- if err = tx.Get(&run, sql, taskID); err != nil {
+ if err = tx.ds.GetContext(ctx, &run, sql, taskID); err != nil {
return fmt.Errorf("failed to find pipeline run for task ID %s: %w", taskID.String(), err)
}
// Update the task with result
sql = `UPDATE pipeline_task_runs SET output = $2, error = $3, finished_at = $4 WHERE id = $1`
- if _, err = tx.Exec(sql, taskID, result.OutputDB(), result.ErrorDB(), time.Now()); err != nil {
+ if _, err = tx.ds.ExecContext(ctx, sql, taskID, result.OutputDB(), result.ErrorDB(), time.Now()); err != nil {
return fmt.Errorf("failed to update pipeline task run: %w", err)
}
@@ -322,21 +362,20 @@ func (o *orm) UpdateTaskRunResult(taskID uuid.UUID, result Result) (run Run, sta
run.State = RunStatusRunning
sql = `UPDATE pipeline_runs SET state = $2 WHERE id = $1`
- if _, err = tx.Exec(sql, run.ID, run.State); err != nil {
+ if _, err = tx.ds.ExecContext(ctx, sql, run.ID, run.State); err != nil {
return fmt.Errorf("failed to update pipeline run state: %w", err)
}
}
- return loadAssociations(tx, []*Run{&run})
+ return loadAssociations(ctx, tx.ds, []*Run{&run})
})
return run, start, err
}
// InsertFinishedRuns inserts all the given runs into the database.
-func (o *orm) InsertFinishedRuns(runs []*Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
- q := o.q.WithOpts(qopts...)
- err := q.Transaction(func(tx pg.Queryer) error {
+func (o *orm) InsertFinishedRuns(ctx context.Context, runs []*Run, saveSuccessfulTaskRuns bool) error {
+ err := o.transact(ctx, func(tx *orm) error {
pipelineRunsQuery := `
INSERT INTO pipeline_runs
(pipeline_spec_id, pruning_key, meta, all_errors, fatal_errors, inputs, outputs, created_at, finished_at, state)
@@ -344,7 +383,7 @@ VALUES
(:pipeline_spec_id, :pruning_key, :meta, :all_errors, :fatal_errors, :inputs, :outputs, :created_at, :finished_at, :state)
RETURNING id
`
- rows, errQ := tx.NamedQuery(pipelineRunsQuery, runs)
+ rows, errQ := sqlx.NamedQueryContext(ctx, tx.ds, pipelineRunsQuery, runs)
if errQ != nil {
return errors.Wrap(errQ, "inserting finished pipeline runs")
}
@@ -369,7 +408,7 @@ RETURNING id
defer func() {
for pruningKey := range pruningKeysm {
- o.Prune(tx, pruningKey)
+ o.prune(tx.ds, pruningKey)
}
}()
@@ -385,7 +424,7 @@ VALUES (:pipeline_run_id, :id, :type, :index, :output, :error, :dot_id, :created
pipelineTaskRuns = append(pipelineTaskRuns, run.PipelineTaskRuns...)
}
- _, errE := tx.NamedExec(pipelineTaskRunsQuery, pipelineTaskRuns)
+ _, errE := tx.ds.NamedExecContext(ctx, pipelineTaskRunsQuery, pipelineTaskRuns)
return errors.Wrap(errE, "insert pipeline task runs")
})
return errors.Wrap(err, "InsertFinishedRuns failed")
@@ -411,7 +450,7 @@ func (o *orm) checkFinishedRun(run *Run, saveSuccessfulTaskRuns bool) error {
// If saveSuccessfulTaskRuns = false, we only save errored runs.
// That way if the job is run frequently (such as OCR) we avoid saving a large number of successful task runs
// which do not provide much value.
-func (o *orm) InsertFinishedRun(run *Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) (err error) {
+func (o *orm) InsertFinishedRun(ctx context.Context, run *Run, saveSuccessfulTaskRuns bool) (err error) {
if err = o.checkFinishedRun(run, saveSuccessfulTaskRuns); err != nil {
return err
}
@@ -421,13 +460,12 @@ func (o *orm) InsertFinishedRun(run *Run, saveSuccessfulTaskRuns bool, qopts ...
return nil
}
- q := o.q.WithOpts(qopts...)
- err = q.Transaction(o.insertFinishedRunTx(run, saveSuccessfulTaskRuns))
+ err = o.insertFinishedRun(ctx, run, saveSuccessfulTaskRuns)
return errors.Wrap(err, "InsertFinishedRun failed")
}
// InsertFinishedRunWithSpec works like InsertFinishedRun but also inserts the pipeline spec.
-func (o *orm) InsertFinishedRunWithSpec(run *Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) (err error) {
+func (o *orm) InsertFinishedRunWithSpec(ctx context.Context, run *Run, saveSuccessfulTaskRuns bool) (err error) {
if err = o.checkFinishedRun(run, saveSuccessfulTaskRuns); err != nil {
return err
}
@@ -437,57 +475,55 @@ func (o *orm) InsertFinishedRunWithSpec(run *Run, saveSuccessfulTaskRuns bool, q
return nil
}
- q := o.q.WithOpts(qopts...)
- err = q.Transaction(func(tx pg.Queryer) error {
+ err = o.transact(ctx, func(tx *orm) error {
sqlStmt1 := `INSERT INTO pipeline_specs (dot_dag_source, max_task_duration, created_at)
VALUES ($1, $2, NOW())
RETURNING id;`
- err = tx.Get(&run.PipelineSpecID, sqlStmt1, run.PipelineSpec.DotDagSource, run.PipelineSpec.MaxTaskDuration)
+ err = tx.ds.GetContext(ctx, &run.PipelineSpecID, sqlStmt1, run.PipelineSpec.DotDagSource, run.PipelineSpec.MaxTaskDuration)
if err != nil {
return errors.Wrap(err, "failed to insert pipeline_specs")
}
// This `job_pipeline_specs` record won't be primary since when this method is called, the job already exists, so it will have primary record.
sqlStmt2 := `INSERT INTO job_pipeline_specs (job_id, pipeline_spec_id, is_primary) VALUES ($1, $2, false)`
- _, err = tx.Exec(sqlStmt2, run.JobID, run.PipelineSpecID)
+ _, err = tx.ds.ExecContext(ctx, sqlStmt2, run.JobID, run.PipelineSpecID)
if err != nil {
return errors.Wrap(err, "failed to insert job_pipeline_specs")
}
- return o.insertFinishedRunTx(run, saveSuccessfulTaskRuns)(tx)
+ return tx.insertFinishedRun(ctx, run, saveSuccessfulTaskRuns)
})
return errors.Wrap(err, "InsertFinishedRun failed")
}
-func (o *orm) insertFinishedRunTx(run *Run, saveSuccessfulTaskRuns bool) func(tx pg.Queryer) error {
- return func(tx pg.Queryer) error {
- sql := `INSERT INTO pipeline_runs (pipeline_spec_id, pruning_key, meta, all_errors, fatal_errors, inputs, outputs, created_at, finished_at, state)
+func (o *orm) insertFinishedRun(ctx context.Context, run *Run, saveSuccessfulTaskRuns bool) error {
+ sql := `INSERT INTO pipeline_runs (pipeline_spec_id, pruning_key, meta, all_errors, fatal_errors, inputs, outputs, created_at, finished_at, state)
VALUES (:pipeline_spec_id, :pruning_key, :meta, :all_errors, :fatal_errors, :inputs, :outputs, :created_at, :finished_at, :state)
RETURNING id;`
- query, args, e := tx.BindNamed(sql, run)
- if e != nil {
- return errors.Wrap(e, "failed to bind")
- }
+ query, args, err := o.ds.BindNamed(sql, run)
+ if err != nil {
+ return errors.Wrap(err, "failed to bind")
+ }
- if err := tx.QueryRowx(query, args...).Scan(&run.ID); err != nil {
- return errors.Wrap(err, "error inserting finished pipeline_run")
- }
+ if err = o.ds.QueryRowxContext(ctx, query, args...).Scan(&run.ID); err != nil {
+ return errors.Wrap(err, "error inserting finished pipeline_run")
+ }
- // update the ID key everywhere
- for i := range run.PipelineTaskRuns {
- run.PipelineTaskRuns[i].PipelineRunID = run.ID
- }
+ // update the ID key everywhere
+ for i := range run.PipelineTaskRuns {
+ run.PipelineTaskRuns[i].PipelineRunID = run.ID
+ }
- if !saveSuccessfulTaskRuns && !run.HasErrors() {
- return nil
- }
+ if !saveSuccessfulTaskRuns && !run.HasErrors() {
+ return nil
+ }
- defer o.Prune(tx, run.PruningKey)
- sql = `
+ defer o.prune(o.ds, run.PruningKey)
+ sql = `
INSERT INTO pipeline_task_runs (pipeline_run_id, id, type, index, output, error, dot_id, created_at, finished_at)
VALUES (:pipeline_run_id, :id, :type, :index, :output, :error, :dot_id, :created_at, :finished_at);`
- _, err := tx.NamedExec(sql, run.PipelineTaskRuns)
- return errors.Wrap(err, "failed to insert pipeline_task_runs")
- }
+ _, err = o.ds.NamedExecContext(ctx, sql, run.PipelineTaskRuns)
+ return errors.Wrap(err, "failed to insert pipeline_task_runs")
+
}
// DeleteRunsOlderThan deletes all pipeline_runs that have been finished for a certain threshold to free DB space
@@ -495,14 +531,12 @@ func (o *orm) insertFinishedRunTx(run *Run, saveSuccessfulTaskRuns bool) func(tx
func (o *orm) DeleteRunsOlderThan(ctx context.Context, threshold time.Duration) error {
start := time.Now()
- q := o.q.WithOpts(pg.WithParentCtxInheritTimeout(ctx))
-
queryThreshold := start.Add(-threshold)
rowsDeleted := int64(0)
err := pg.Batch(func(_, limit uint) (count uint, err error) {
- result, cancel, err := q.ExecQIter(`
+ result, err := o.ds.ExecContext(ctx, `
WITH batched_pipeline_runs AS (
SELECT * FROM pipeline_runs
WHERE finished_at < ($1)
@@ -515,7 +549,6 @@ WHERE pipeline_runs.id = batched_pipeline_runs.id`,
queryThreshold,
limit,
)
- defer cancel()
if err != nil {
return count, errors.Wrap(err, "DeleteRunsOlderThan failed to delete old pipeline_runs")
}
@@ -539,7 +572,7 @@ WHERE pipeline_runs.id = batched_pipeline_runs.id`,
o.lggr.Debugw("pipeline_runs reaper VACUUM ANALYZE query completed", "duration", time.Since(start))
}(deleteTS)
- err = q.ExecQ("VACUUM ANALYZE pipeline_runs")
+ _, err = o.ds.ExecContext(ctx, "VACUUM ANALYZE pipeline_runs")
if err != nil {
o.lggr.Warnw("DeleteRunsOlderThan successfully deleted old pipeline_runs rows, but failed to run VACUUM ANALYZE", "err", err)
return nil
@@ -548,13 +581,13 @@ WHERE pipeline_runs.id = batched_pipeline_runs.id`,
return nil
}
-func (o *orm) FindRun(id int64) (r Run, err error) {
+func (o *orm) FindRun(ctx context.Context, id int64) (r Run, err error) {
var runs []*Run
- err = o.q.Transaction(func(tx pg.Queryer) error {
- if err = tx.Select(&runs, `SELECT * from pipeline_runs WHERE id = $1 LIMIT 1`, id); err != nil {
+ err = o.transact(ctx, func(tx *orm) error {
+ if err = tx.ds.SelectContext(ctx, &runs, `SELECT * from pipeline_runs WHERE id = $1 LIMIT 1`, id); err != nil {
return errors.Wrap(err, "failed to load runs")
}
- return loadAssociations(tx, runs)
+ return loadAssociations(ctx, tx.ds, runs)
})
if len(runs) == 0 {
return r, sql.ErrNoRows
@@ -562,15 +595,15 @@ func (o *orm) FindRun(id int64) (r Run, err error) {
return *runs[0], err
}
-func (o *orm) GetAllRuns() (runs []Run, err error) {
+func (o *orm) GetAllRuns(ctx context.Context) (runs []Run, err error) {
var runsPtrs []*Run
- err = o.q.Transaction(func(tx pg.Queryer) error {
- err = tx.Select(&runsPtrs, `SELECT * from pipeline_runs ORDER BY created_at ASC, id ASC`)
+ err = o.transact(ctx, func(tx *orm) error {
+ err = tx.ds.SelectContext(ctx, &runsPtrs, `SELECT * from pipeline_runs ORDER BY created_at ASC, id ASC`)
if err != nil {
return errors.Wrap(err, "failed to load runs")
}
- return loadAssociations(tx, runsPtrs)
+ return loadAssociations(ctx, tx.ds, runsPtrs)
})
runs = make([]Run, len(runsPtrs))
for i, runPtr := range runsPtrs {
@@ -580,17 +613,16 @@ func (o *orm) GetAllRuns() (runs []Run, err error) {
}
func (o *orm) GetUnfinishedRuns(ctx context.Context, now time.Time, fn func(run Run) error) error {
- q := o.q.WithOpts(pg.WithParentCtx(ctx))
return pg.Batch(func(offset, limit uint) (count uint, err error) {
var runs []*Run
- err = q.Transaction(func(tx pg.Queryer) error {
- err = tx.Select(&runs, `SELECT * from pipeline_runs WHERE state = $1 AND created_at < $2 ORDER BY created_at ASC, id ASC OFFSET $3 LIMIT $4`, RunStatusRunning, now, offset, limit)
+ err = o.transact(ctx, func(tx *orm) error {
+ err = tx.ds.SelectContext(ctx, &runs, `SELECT * from pipeline_runs WHERE state = $1 AND created_at < $2 ORDER BY created_at ASC, id ASC OFFSET $3 LIMIT $4`, RunStatusRunning, now, offset, limit)
if err != nil {
return errors.Wrap(err, "failed to load runs")
}
- err = loadAssociations(tx, runs)
+ err = loadAssociations(ctx, tx.ds, runs)
if err != nil {
return err
}
@@ -608,7 +640,7 @@ func (o *orm) GetUnfinishedRuns(ctx context.Context, now time.Time, fn func(run
}
// loads PipelineSpec and PipelineTaskRuns for Runs in exactly 2 queries
-func loadAssociations(q pg.Queryer, runs []*Run) error {
+func loadAssociations(ctx context.Context, ds sqlutil.DataSource, runs []*Run) error {
if len(runs) == 0 {
return nil
}
@@ -635,7 +667,7 @@ func loadAssociations(q pg.Queryer, runs []*Run) error {
LEFT JOIN job_pipeline_specs jps ON jps.pipeline_spec_id=ps.id
LEFT JOIN jobs ON jobs.id=jps.job_id
WHERE ps.id = ANY($1)`
- if err := q.Select(&specs, sqlQuery, pipelineSpecIDs); err != nil {
+ if err := ds.SelectContext(ctx, &specs, sqlQuery, pipelineSpecIDs); err != nil {
return errors.Wrap(err, "failed to postload pipeline_specs for runs")
}
for _, spec := range specs {
@@ -647,7 +679,7 @@ func loadAssociations(q pg.Queryer, runs []*Run) error {
var taskRuns []TaskRun
taskRunPRIDM := make(map[int64][]TaskRun, len(runs)) // keyed by pipelineRunID
- if err := q.Select(&taskRuns, `SELECT * FROM pipeline_task_runs WHERE pipeline_run_id = ANY($1) ORDER BY created_at ASC, id ASC`, pipelineRunIDs); err != nil {
+ if err := ds.SelectContext(ctx, &taskRuns, `SELECT * FROM pipeline_task_runs WHERE pipeline_run_id = ANY($1) ORDER BY created_at ASC, id ASC`, pipelineRunIDs); err != nil {
return errors.Wrap(err, "failed to postload pipeline_task_runs for runs")
}
for _, taskRun := range taskRuns {
@@ -662,10 +694,6 @@ func loadAssociations(q pg.Queryer, runs []*Run) error {
return nil
}
-func (o *orm) GetQ() pg.Q {
- return o.q
-}
-
func (o *orm) loadCount(jobID int32) *atomic.Uint64 {
// fast path; avoids allocation
actual, exists := o.pm.Load(jobID)
@@ -681,7 +709,7 @@ func (o *orm) loadCount(jobID int32) *atomic.Uint64 {
// this value or higher
const syncLimit = 1000
-// Prune attempts to keep the pipeline_runs table capped close to the
+// prune attempts to keep the pipeline_runs table capped close to the
// maxSuccessfulRuns length for each job_id.
//
// It does this synchronously for small values and async/sampled for large
@@ -689,13 +717,13 @@ const syncLimit = 1000
//
// Note this does not guarantee the pipeline_runs table is kept to exactly the
// max length, rather that it doesn't excessively larger than it.
-func (o *orm) Prune(tx pg.Queryer, jobID int32) {
+func (o *orm) prune(ds sqlutil.DataSource, jobID int32) {
if jobID == 0 {
o.lggr.Panic("expected a non-zero job ID")
}
// For small maxSuccessfulRuns its fast enough to prune every time
if o.maxSuccessfulRuns < syncLimit {
- o.execPrune(tx, jobID)
+ o.execPrune(o.ctx, ds, jobID)
return
}
// for large maxSuccessfulRuns we do it async on a sampled basis
@@ -708,9 +736,11 @@ func (o *orm) Prune(tx pg.Queryer, jobID int32) {
go func() {
o.lggr.Debugw("Pruning runs", "jobID", jobID, "count", val, "every", every, "maxSuccessfulRuns", o.maxSuccessfulRuns)
defer o.wg.Done()
- // Must not use tx here since it's async and the transaction
+ // Must not use ds here since it's async and the transaction
// could be stale
- o.execPrune(o.q.WithOpts(pg.WithLongQueryTimeout()), jobID)
+ ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(o.ctx), time.Minute)
+ defer cancel()
+ o.execPrune(ctx, o.ds, jobID)
}()
})
if !ok {
@@ -720,8 +750,8 @@ func (o *orm) Prune(tx pg.Queryer, jobID int32) {
}
}
-func (o *orm) execPrune(q pg.Queryer, jobID int32) {
- res, err := q.ExecContext(o.ctx, `DELETE FROM pipeline_runs WHERE pruning_key = $1 AND state = $2 AND id NOT IN (
+func (o *orm) execPrune(ctx context.Context, ds sqlutil.DataSource, jobID int32) {
+ res, err := ds.ExecContext(o.ctx, `DELETE FROM pipeline_runs WHERE pruning_key = $1 AND state = $2 AND id NOT IN (
SELECT id FROM pipeline_runs
WHERE pruning_key = $1 AND state = $2
ORDER BY id DESC
@@ -739,7 +769,7 @@ LIMIT $3
if rowsAffected == 0 {
// check the spec still exists and garbage collect if necessary
var exists bool
- if err := q.GetContext(o.ctx, &exists, `SELECT EXISTS(SELECT ps.* FROM pipeline_specs ps JOIN job_pipeline_specs jps ON (ps.id=jps.pipeline_spec_id) WHERE jps.job_id = $1)`, jobID); err != nil {
+ if err := ds.GetContext(ctx, &exists, `SELECT EXISTS(SELECT ps.* FROM pipeline_specs ps JOIN job_pipeline_specs jps ON (ps.id=jps.pipeline_spec_id) WHERE jps.job_id = $1)`, jobID); err != nil {
o.lggr.Errorw("Failed check existence of pipeline_spec while pruning runs", "err", err, "jobID", jobID)
return
}
diff --git a/core/services/pipeline/orm_test.go b/core/services/pipeline/orm_test.go
index c59fc0c32c6..88155bc04ba 100644
--- a/core/services/pipeline/orm_test.go
+++ b/core/services/pipeline/orm_test.go
@@ -71,11 +71,11 @@ func setupORM(t *testing.T, heavy bool) (db *sqlx.DB, orm pipeline.ORM, jorm job
db = pgtest.NewSqlxDB(t)
}
cfg := ormconfig{pgtest.NewQConfig(true)}
- orm = pipeline.NewORM(db, logger.TestLogger(t), cfg, cfg.JobPipelineMaxSuccessfulRuns())
+ orm = pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipelineMaxSuccessfulRuns())
config := configtest.NewTestGeneralConfig(t)
lggr := logger.TestLogger(t)
keyStore := cltest.NewKeyStore(t, db, config.Database())
- bridgeORM := bridges.NewORM(db, lggr, config.Database())
+ bridgeORM := bridges.NewORM(db)
jorm = job.NewORM(db, orm, bridgeORM, keyStore, lggr, config.Database())
@@ -91,6 +91,7 @@ func setupLiteORM(t *testing.T) (db *sqlx.DB, orm pipeline.ORM, jorm job.ORM) {
}
func Test_PipelineORM_CreateSpec(t *testing.T) {
+ ctx := testutils.Context(t)
db, orm, _ := setupLiteORM(t)
var (
@@ -102,7 +103,7 @@ func Test_PipelineORM_CreateSpec(t *testing.T) {
Source: source,
}
- id, err := orm.CreateSpec(p, maxTaskDuration)
+ id, err := orm.CreateSpec(ctx, nil, p, maxTaskDuration)
require.NoError(t, err)
actual := pipeline.Spec{}
@@ -121,7 +122,8 @@ func Test_PipelineORM_FindRun(t *testing.T) {
require.NoError(t, err)
expected := mustInsertPipelineRun(t, orm)
- run, err := orm.FindRun(expected.ID)
+ ctx := testutils.Context(t)
+ run, err := orm.FindRun(ctx, expected.ID)
require.NoError(t, err)
require.Equal(t, expected.ID, run.ID)
@@ -138,12 +140,14 @@ func mustInsertPipelineRun(t *testing.T, orm pipeline.ORM) pipeline.Run {
FinishedAt: null.Time{},
}
- require.NoError(t, orm.InsertRun(&run))
+ ctx := testutils.Context(t)
+ require.NoError(t, orm.InsertRun(ctx, &run))
return run
}
func mustInsertAsyncRun(t *testing.T, orm pipeline.ORM, jobORM job.ORM) *pipeline.Run {
t.Helper()
+ ctx := testutils.Context(t)
s := `
ds1 [type=bridge async=true name="example-bridge" timeout=0 requestData=<{"data": {"coin": "BTC", "market": "USD"}}>]
@@ -178,12 +182,13 @@ answer2 [type=bridge name=election_winner index=1];
CreatedAt: time.Now(),
}
- err = orm.CreateRun(run)
+ err = orm.CreateRun(ctx, run)
require.NoError(t, err)
return run
}
func TestInsertFinishedRuns(t *testing.T) {
+ ctx := testutils.Context(t)
db, orm, _ := setupLiteORM(t)
_, err := db.Exec(`SET CONSTRAINTS fk_pipeline_runs_pruning_key DEFERRED`)
@@ -207,7 +212,7 @@ func TestInsertFinishedRuns(t *testing.T) {
Outputs: jsonserializable.JSONSerializable{},
}
- require.NoError(t, orm.InsertRun(&r))
+ require.NoError(t, orm.InsertRun(ctx, &r))
r.PipelineTaskRuns = []pipeline.TaskRun{
{
@@ -238,12 +243,13 @@ func TestInsertFinishedRuns(t *testing.T) {
runs = append(runs, &r)
}
- err = orm.InsertFinishedRuns(runs, true)
+ err = orm.InsertFinishedRuns(ctx, runs, true)
require.NoError(t, err)
}
func Test_PipelineORM_InsertFinishedRunWithSpec(t *testing.T) {
+ ctx := testutils.Context(t)
db, orm, jorm := setupLiteORM(t)
s := `
@@ -314,7 +320,7 @@ answer2 [type=bridge name=election_winner index=1];
run.AllErrors = append(run.AllErrors, null.NewString("", false))
run.State = pipeline.RunStatusCompleted
- err = orm.InsertFinishedRunWithSpec(run, true)
+ err = orm.InsertFinishedRunWithSpec(ctx, run, true)
require.NoError(t, err)
var pipelineSpec pipeline.Spec
@@ -330,6 +336,7 @@ answer2 [type=bridge name=election_winner index=1];
// Tests that inserting run results, then later updating the run results via upsert will work correctly.
func Test_PipelineORM_StoreRun_ShouldUpsert(t *testing.T) {
+ ctx := testutils.Context(t)
_, orm, jorm := setupLiteORM(t)
run := mustInsertAsyncRun(t, orm, jorm)
@@ -357,14 +364,14 @@ func Test_PipelineORM_StoreRun_ShouldUpsert(t *testing.T) {
FinishedAt: null.TimeFrom(now),
},
}
- restart, err := orm.StoreRun(run)
+ restart, err := orm.StoreRun(ctx, run)
require.NoError(t, err)
// no new data, so we don't need a restart
require.Equal(t, false, restart)
// the run is paused
require.Equal(t, pipeline.RunStatusSuspended, run.State)
- r, err := orm.FindRun(run.ID)
+ r, err := orm.FindRun(ctx, run.ID)
require.NoError(t, err)
run = &r
// this is an incomplete run, so partial results should be present (regardless of saveSuccessfulTaskRuns)
@@ -388,14 +395,14 @@ func Test_PipelineORM_StoreRun_ShouldUpsert(t *testing.T) {
FinishedAt: null.TimeFrom(now),
},
}
- restart, err = orm.StoreRun(run)
+ restart, err = orm.StoreRun(ctx, run)
require.NoError(t, err)
// no new data, so we don't need a restart
require.Equal(t, false, restart)
// the run is paused
require.Equal(t, pipeline.RunStatusSuspended, run.State)
- r, err = orm.FindRun(run.ID)
+ r, err = orm.FindRun(ctx, run.ID)
require.NoError(t, err)
run = &r
// this is an incomplete run, so partial results should be present (regardless of saveSuccessfulTaskRuns)
@@ -409,11 +416,12 @@ func Test_PipelineORM_StoreRun_ShouldUpsert(t *testing.T) {
// Tests that trying to persist a partial run while new data became available (i.e. via /v2/restart)
// will detect a restart and update the result data on the Run.
func Test_PipelineORM_StoreRun_DetectsRestarts(t *testing.T) {
+ ctx := testutils.Context(t)
db, orm, jorm := setupLiteORM(t)
run := mustInsertAsyncRun(t, orm, jorm)
- r, err := orm.FindRun(run.ID)
+ r, err := orm.FindRun(ctx, run.ID)
require.NoError(t, err)
require.Equal(t, run.Inputs, r.Inputs)
@@ -459,7 +467,7 @@ func Test_PipelineORM_StoreRun_DetectsRestarts(t *testing.T) {
},
}
- restart, err := orm.StoreRun(run)
+ restart, err := orm.StoreRun(ctx, run)
require.NoError(t, err)
// new data available! immediately restart the run
require.Equal(t, true, restart)
@@ -474,6 +482,7 @@ func Test_PipelineORM_StoreRun_DetectsRestarts(t *testing.T) {
}
func Test_PipelineORM_StoreRun_UpdateTaskRunResult(t *testing.T) {
+ ctx := testutils.Context(t)
_, orm, jorm := setupLiteORM(t)
run := mustInsertAsyncRun(t, orm, jorm)
@@ -525,13 +534,13 @@ func Test_PipelineORM_StoreRun_UpdateTaskRunResult(t *testing.T) {
require.Equal(t, pipeline.RunStatusRunning, run.State)
// Now store a partial run
- restart, err := orm.StoreRun(run)
+ restart, err := orm.StoreRun(ctx, run)
require.NoError(t, err)
require.False(t, restart)
// assert that run should be in "paused" state
require.Equal(t, pipeline.RunStatusSuspended, run.State)
- r, start, err := orm.UpdateTaskRunResult(ds1_id, pipeline.Result{Value: "foo"})
+ r, start, err := orm.UpdateTaskRunResult(ctx, ds1_id, pipeline.Result{Value: "foo"})
run = &r
require.NoError(t, err)
assert.Greater(t, run.ID, int64(0))
@@ -555,6 +564,7 @@ func Test_PipelineORM_StoreRun_UpdateTaskRunResult(t *testing.T) {
}
func Test_PipelineORM_DeleteRun(t *testing.T) {
+ ctx := testutils.Context(t)
_, orm, jorm := setupLiteORM(t)
run := mustInsertAsyncRun(t, orm, jorm)
@@ -582,21 +592,22 @@ func Test_PipelineORM_DeleteRun(t *testing.T) {
FinishedAt: null.TimeFrom(now),
},
}
- restart, err := orm.StoreRun(run)
+ restart, err := orm.StoreRun(ctx, run)
require.NoError(t, err)
// no new data, so we don't need a restart
require.Equal(t, false, restart)
// the run is paused
require.Equal(t, pipeline.RunStatusSuspended, run.State)
- err = orm.DeleteRun(run.ID)
+ err = orm.DeleteRun(ctx, run.ID)
require.NoError(t, err)
- _, err = orm.FindRun(run.ID)
+ _, err = orm.FindRun(ctx, run.ID)
require.Error(t, err, "not found")
}
func Test_PipelineORM_DeleteRunsOlderThan(t *testing.T) {
+ ctx := testutils.Context(t)
_, orm, jorm := setupHeavyORM(t)
var runsIds []int64
@@ -623,7 +634,7 @@ func Test_PipelineORM_DeleteRunsOlderThan(t *testing.T) {
run.Outputs = jsonserializable.JSONSerializable{Val: 1, Valid: true}
run.AllErrors = pipeline.RunErrors{null.StringFrom("SOMETHING")}
- restart, err := orm.StoreRun(run)
+ restart, err := orm.StoreRun(ctx, run)
assert.NoError(t, err)
// no new data, so we don't need a restart
assert.Equal(t, false, restart)
@@ -635,13 +646,14 @@ func Test_PipelineORM_DeleteRunsOlderThan(t *testing.T) {
assert.NoError(t, err)
for _, runId := range runsIds {
- _, err := orm.FindRun(runId)
+ _, err := orm.FindRun(ctx, runId)
require.Error(t, err, "not found")
}
}
func Test_GetUnfinishedRuns_Keepers(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
// The test configures single Keeper job with two running tasks.
// GetUnfinishedRuns() expects to catch both running tasks.
@@ -650,8 +662,8 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) {
lggr := logger.TestLogger(t)
db := pgtest.NewSqlxDB(t)
keyStore := cltest.NewKeyStore(t, db, config.Database())
- porm := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgeORM := bridges.NewORM(db, lggr, config.Database())
+ porm := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgeORM := bridges.NewORM(db)
jorm := job.NewORM(db, porm, bridgeORM, keyStore, lggr, config.Database())
defer func() { assert.NoError(t, jorm.Close()) }()
@@ -684,7 +696,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) {
runID1 := uuid.New()
runID2 := uuid.New()
- err = porm.CreateRun(&pipeline.Run{
+ err = porm.CreateRun(ctx, &pipeline.Run{
PipelineSpecID: keeperJob.PipelineSpecID,
PruningKey: keeperJob.ID,
State: pipeline.RunStatusRunning,
@@ -701,7 +713,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) {
})
require.NoError(t, err)
- err = porm.CreateRun(&pipeline.Run{
+ err = porm.CreateRun(ctx, &pipeline.Run{
PipelineSpecID: keeperJob.PipelineSpecID,
PruningKey: keeperJob.ID,
State: pipeline.RunStatusRunning,
@@ -744,6 +756,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) {
func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
// The test configures single DR job with two task runs: one is running and one is suspended.
// GetUnfinishedRuns() expects to catch the one that is running.
@@ -752,8 +765,8 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) {
lggr := logger.TestLogger(t)
db := pgtest.NewSqlxDB(t)
keyStore := cltest.NewKeyStore(t, db, config.Database())
- porm := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
- bridgeORM := bridges.NewORM(db, lggr, config.Database())
+ porm := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns())
+ bridgeORM := bridges.NewORM(db)
jorm := job.NewORM(db, porm, bridgeORM, keyStore, lggr, config.Database())
defer func() { assert.NoError(t, jorm.Close()) }()
@@ -784,7 +797,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) {
runningID := uuid.New()
- err = porm.CreateRun(&pipeline.Run{
+ err = porm.CreateRun(ctx, &pipeline.Run{
PipelineSpecID: drJob.PipelineSpecID,
PruningKey: drJob.ID,
State: pipeline.RunStatusRunning,
@@ -801,7 +814,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) {
})
require.NoError(t, err)
- err = porm.CreateRun(&pipeline.Run{
+ err = porm.CreateRun(ctx, &pipeline.Run{
PipelineSpecID: drJob.PipelineSpecID,
PruningKey: drJob.ID,
State: pipeline.RunStatusSuspended,
@@ -846,7 +859,7 @@ func Test_Prune(t *testing.T) {
})
lggr, observed := logger.TestLoggerObserved(t, zapcore.DebugLevel)
db := pgtest.NewSqlxDB(t)
- porm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
+ porm := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns())
torm := newTestORM(porm, db)
ps1 := cltest.MustInsertPipelineSpec(t, db)
diff --git a/core/services/pipeline/runner.go b/core/services/pipeline/runner.go
index 08d371716fc..862d2f49178 100644
--- a/core/services/pipeline/runner.go
+++ b/core/services/pipeline/runner.go
@@ -15,6 +15,7 @@ import (
"gopkg.in/guregu/null.v4"
"github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils"
"github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable"
@@ -23,7 +24,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/config/env"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/recovery"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -36,15 +36,16 @@ type Runner interface {
// Run is a blocking call that will execute the run until no further progress can be made.
// If `incomplete` is true, the run is only partially complete and is suspended, awaiting to be resumed when more data comes in.
// Note that `saveSuccessfulTaskRuns` value is ignored if the run contains async tasks.
- Run(ctx context.Context, run *Run, l logger.Logger, saveSuccessfulTaskRuns bool, fn func(tx pg.Queryer) error) (incomplete bool, err error)
- ResumeRun(taskID uuid.UUID, value interface{}, err error) error
+ Run(ctx context.Context, run *Run, l logger.Logger, saveSuccessfulTaskRuns bool, fn func(tx sqlutil.DataSource) error) (incomplete bool, err error)
+ ResumeRun(ctx context.Context, taskID uuid.UUID, value interface{}, err error) error
// ExecuteRun executes a new run in-memory according to a spec and returns the results.
// We expect spec.JobID and spec.JobName to be set for logging/prometheus.
ExecuteRun(ctx context.Context, spec Spec, vars Vars, l logger.Logger) (run *Run, trrs TaskRunResults, err error)
// InsertFinishedRun saves the run results in the database.
- InsertFinishedRun(run *Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error
- InsertFinishedRuns(runs []*Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error
+ // ds is an optional override, for example when executing a transaction.
+ InsertFinishedRun(ctx context.Context, ds sqlutil.DataSource, run *Run, saveSuccessfulTaskRuns bool) error
+ InsertFinishedRuns(ctx context.Context, ds sqlutil.DataSource, runs []*Run, saveSuccessfulTaskRuns bool) error
// ExecuteAndInsertFinishedRun executes a new run in-memory according to a spec, persists and saves the results.
// It is a combination of ExecuteRun and InsertFinishedRun.
@@ -566,9 +567,9 @@ func (r *runner) ExecuteAndInsertFinishedRun(ctx context.Context, spec Spec, var
}
if spec.ID == 0 {
- err = r.orm.InsertFinishedRunWithSpec(run, saveSuccessfulTaskRuns)
+ err = r.orm.InsertFinishedRunWithSpec(ctx, run, saveSuccessfulTaskRuns)
} else {
- err = r.orm.InsertFinishedRun(run, saveSuccessfulTaskRuns)
+ err = r.orm.InsertFinishedRun(ctx, run, saveSuccessfulTaskRuns)
}
if err != nil {
return 0, trrs, pkgerrors.Wrapf(err, "error inserting finished results for spec ID %v", run.PipelineSpecID)
@@ -577,7 +578,7 @@ func (r *runner) ExecuteAndInsertFinishedRun(ctx context.Context, spec Spec, var
}
-func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccessfulTaskRuns bool, fn func(tx pg.Queryer) error) (incomplete bool, err error) {
+func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccessfulTaskRuns bool, fn func(tx sqlutil.DataSource) error) (incomplete bool, err error) {
pipeline, err := r.InitializePipeline(run.PipelineSpec)
if err != nil {
return false, err
@@ -594,8 +595,7 @@ func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccess
preinsert := pipeline.RequiresPreInsert()
- q := r.orm.GetQ().WithOpts(pg.WithParentCtx(ctx))
- err = q.Transaction(func(tx pg.Queryer) error {
+ err = r.orm.Transact(ctx, func(tx ORM) error {
// OPTIMISATION: avoid an extra db write if there is no async tasks present or if this is a resumed run
if preinsert && run.ID == 0 {
now := time.Now()
@@ -614,13 +614,13 @@ func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccess
default:
}
}
- if err = r.orm.CreateRun(run, pg.WithQueryer(tx)); err != nil {
+ if err = tx.CreateRun(ctx, run); err != nil {
return err
}
}
if fn != nil {
- return fn(tx)
+ return fn(tx.DataSource())
}
return nil
})
@@ -634,14 +634,14 @@ func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccess
if preinsert {
// FailSilently = run failed and task was marked failEarly. skip StoreRun and instead delete all trace of it
if run.FailSilently {
- if err = r.orm.DeleteRun(run.ID); err != nil {
+ if err = r.orm.DeleteRun(ctx, run.ID); err != nil {
return false, pkgerrors.Wrap(err, "Run")
}
return false, nil
}
var restart bool
- restart, err = r.orm.StoreRun(run)
+ restart, err = r.orm.StoreRun(ctx, run)
if err != nil {
return false, pkgerrors.Wrapf(err, "error storing run for spec ID %v state %v outputs %v errors %v finished_at %v",
run.PipelineSpec.ID, run.State, run.Outputs, run.FatalErrors, run.FinishedAt)
@@ -660,7 +660,7 @@ func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccess
return false, nil
}
- if err = r.orm.InsertFinishedRun(run, saveSuccessfulTaskRuns, pg.WithParentCtx(ctx)); err != nil {
+ if err = r.orm.InsertFinishedRun(ctx, run, saveSuccessfulTaskRuns); err != nil {
return false, pkgerrors.Wrapf(err, "error storing run for spec ID %v", run.PipelineSpec.ID)
}
}
@@ -671,8 +671,8 @@ func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccess
}
}
-func (r *runner) ResumeRun(taskID uuid.UUID, value interface{}, err error) error {
- run, start, err := r.orm.UpdateTaskRunResult(taskID, Result{
+func (r *runner) ResumeRun(ctx context.Context, taskID uuid.UUID, value interface{}, err error) error {
+ run, start, err := r.orm.UpdateTaskRunResult(ctx, taskID, Result{
Value: value,
Error: err,
})
@@ -694,12 +694,20 @@ func (r *runner) ResumeRun(taskID uuid.UUID, value interface{}, err error) error
return nil
}
-func (r *runner) InsertFinishedRun(run *Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
- return r.orm.InsertFinishedRun(run, saveSuccessfulTaskRuns, qopts...)
+func (r *runner) InsertFinishedRun(ctx context.Context, ds sqlutil.DataSource, run *Run, saveSuccessfulTaskRuns bool) error {
+ orm := r.orm
+ if ds != nil {
+ orm = orm.WithDataSource(ds)
+ }
+ return orm.InsertFinishedRun(ctx, run, saveSuccessfulTaskRuns)
}
-func (r *runner) InsertFinishedRuns(runs []*Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
- return r.orm.InsertFinishedRuns(runs, saveSuccessfulTaskRuns, qopts...)
+func (r *runner) InsertFinishedRuns(ctx context.Context, ds sqlutil.DataSource, runs []*Run, saveSuccessfulTaskRuns bool) error {
+ orm := r.orm
+ if ds != nil {
+ orm = orm.WithDataSource(ds)
+ }
+ return orm.InsertFinishedRuns(ctx, runs, saveSuccessfulTaskRuns)
}
func (r *runner) runReaper() {
diff --git a/core/services/pipeline/runner_test.go b/core/services/pipeline/runner_test.go
index cdf63aa975f..f27a6b35348 100644
--- a/core/services/pipeline/runner_test.go
+++ b/core/services/pipeline/runner_test.go
@@ -68,10 +68,10 @@ func Test_PipelineRunner_ExecuteTaskRuns(t *testing.T) {
bridgeFeedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()}, cfg.Database())
+ _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()})
btORM := bridgesMocks.NewORM(t)
- btORM.On("FindBridge", bt.Name).Return(*bt, nil).Once()
+ btORM.On("FindBridge", mock.Anything, bt.Name).Return(*bt, nil).Once()
// 2. Setup success HTTP
s2 := httptest.NewServer(fakePriceResponder(t, btcUSDPairing, decimal.NewFromInt(9600), "", nil))
@@ -254,7 +254,7 @@ func Test_PipelineRunner_ExecuteTaskRunsWithVars(t *testing.T) {
cfg.Database())
defer ds1.Close()
- btORM.On("FindBridge", bridge.Name).Return(bridge, nil).Once()
+ btORM.On("FindBridge", mock.Anything, bridge.Name).Return(bridge, nil).Once()
// 2. Setup success HTTP
ds2 := httptest.NewServer(fakeExternalAdapter(t, expectedRequestDS2, map[string]interface{}{
@@ -272,7 +272,7 @@ func Test_PipelineRunner_ExecuteTaskRunsWithVars(t *testing.T) {
submit, submitBt := makeBridge(t, db, expectedRequestSubmit, map[string]interface{}{"ok": true}, cfg.Database())
defer submit.Close()
- btORM.On("FindBridge", submitBt.Name).Return(submitBt, nil).Once()
+ btORM.On("FindBridge", mock.Anything, submitBt.Name).Return(submitBt, nil).Once()
runner, _ := newRunner(t, db, btORM, cfg)
specStr := taskRunWithVars{
@@ -476,7 +476,7 @@ func Test_PipelineRunner_HandleFaultsPersistRun(t *testing.T) {
orm.On("GetQ").Return(q).Maybe()
orm.On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 1
+ args.Get(1).(*pipeline.Run).ID = 1
}).
Return(nil)
cfg := configtest.NewTestGeneralConfig(t)
@@ -517,7 +517,7 @@ func Test_PipelineRunner_ExecuteAndInsertFinishedRun_SavingTheSpec(t *testing.T)
orm.On("GetQ").Return(q).Maybe()
orm.On("InsertFinishedRunWithSpec", mock.Anything, mock.Anything, mock.Anything).
Run(func(args mock.Arguments) {
- args.Get(0).(*pipeline.Run).ID = 1
+ args.Get(1).(*pipeline.Run).ID = 1
}).
Return(nil)
cfg := configtest.NewTestGeneralConfig(t)
@@ -629,7 +629,7 @@ func Test_PipelineRunner_AsyncJob_Basic(t *testing.T) {
require.NoError(t, err)
cfg := configtest.NewTestGeneralConfig(t)
- _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()}, cfg.Database())
+ _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()})
// 2. Setup success HTTP
s2 := httptest.NewServer(fakePriceResponder(t, btcUSDPairing, decimal.NewFromInt(9600), "", nil))
@@ -641,8 +641,14 @@ func Test_PipelineRunner_AsyncJob_Basic(t *testing.T) {
defer s5.Close()
btORM := bridgesMocks.NewORM(t)
- btORM.On("FindBridge", bt.Name).Return(*bt, nil)
+ btORM.On("FindBridge", mock.Anything, bt.Name).Return(*bt, nil)
+
r, orm := newRunner(t, db, btORM, cfg)
+ transactCall := orm.On("Transact", mock.Anything, mock.Anything)
+ transactCall.Run(func(args mock.Arguments) {
+ fn := args[1].(func(orm pipeline.ORM) error)
+ transactCall.ReturnArguments = mock.Arguments{fn(orm)}
+ })
s := fmt.Sprintf(`
ds1 [type=bridge async=true name="%s" timeout=0 requestData=<{"data": {"coin": "BTC", "market": "USD"}}>]
@@ -673,11 +679,11 @@ ds5 [type=http method="GET" url="%s" index=2]
// Start a new run
run := pipeline.NewRun(spec, pipeline.NewVarsFrom(nil))
// we should receive a call to CreateRun because it's contains an async task
- orm.On("CreateRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(nil).Run(func(args mock.Arguments) {
- run := args.Get(0).(*pipeline.Run)
+ orm.On("CreateRun", mock.Anything, mock.AnythingOfType("*pipeline.Run")).Return(nil).Run(func(args mock.Arguments) {
+ run := args.Get(1).(*pipeline.Run)
run.ID = 1 // give it a valid "id"
}).Once()
- orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(false, nil).Once()
+ orm.On("StoreRun", mock.Anything, mock.AnythingOfType("*pipeline.Run")).Return(false, nil).Once()
lggr := logger.TestLogger(t)
incomplete, err := r.Run(testutils.Context(t), run, lggr, false, nil)
require.NoError(t, err)
@@ -687,7 +693,7 @@ ds5 [type=http method="GET" url="%s" index=2]
// TODO: test a pending run that's not marked async=true, that is not allowed
// Trigger run resumption with no new data
- orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run")).Return(false, nil).Once()
+ orm.On("StoreRun", mock.Anything, mock.AnythingOfType("*pipeline.Run")).Return(false, nil).Once()
incomplete, err = r.Run(testutils.Context(t), run, lggr, false, nil)
require.NoError(t, err)
require.Equal(t, true, incomplete) // still incomplete
@@ -700,7 +706,7 @@ ds5 [type=http method="GET" url="%s" index=2]
Valid: true,
}
// Trigger run resumption
- orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(false, nil).Once()
+ orm.On("StoreRun", mock.Anything, mock.AnythingOfType("*pipeline.Run")).Return(false, nil).Once()
incomplete, err = r.Run(testutils.Context(t), run, lggr, false, nil)
require.NoError(t, err)
require.Equal(t, false, incomplete) // done
@@ -755,7 +761,7 @@ func Test_PipelineRunner_AsyncJob_InstantRestart(t *testing.T) {
require.NoError(t, err)
cfg := configtest.NewTestGeneralConfig(t)
- _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()}, cfg.Database())
+ _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()})
// 2. Setup success HTTP
s2 := httptest.NewServer(fakePriceResponder(t, btcUSDPairing, decimal.NewFromInt(9600), "", nil))
@@ -767,9 +773,14 @@ func Test_PipelineRunner_AsyncJob_InstantRestart(t *testing.T) {
defer s5.Close()
btORM := bridgesMocks.NewORM(t)
- btORM.On("FindBridge", bt.Name).Return(*bt, nil)
+ btORM.On("FindBridge", mock.Anything, bt.Name).Return(*bt, nil)
r, orm := newRunner(t, db, btORM, cfg)
+ transactCall := orm.On("Transact", mock.Anything, mock.Anything)
+ transactCall.Run(func(args mock.Arguments) {
+ fn := args[1].(func(orm pipeline.ORM) error)
+ transactCall.ReturnArguments = mock.Arguments{fn(orm)}
+ })
s := fmt.Sprintf(`
ds1 [type=bridge async=true name="%s" timeout=0 requestData=<{"data": {"coin": "BTC", "market": "USD"}}>]
@@ -800,13 +811,13 @@ ds5 [type=http method="GET" url="%s" index=2]
// Start a new run
run := pipeline.NewRun(spec, pipeline.NewVarsFrom(nil))
// we should receive a call to CreateRun because it's contains an async task
- orm.On("CreateRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(nil).Run(func(args mock.Arguments) {
- run := args.Get(0).(*pipeline.Run)
+ orm.On("CreateRun", mock.Anything, mock.AnythingOfType("*pipeline.Run")).Return(nil).Run(func(args mock.Arguments) {
+ run := args.Get(1).(*pipeline.Run)
run.ID = 1 // give it a valid "id"
}).Once()
// Simulate updated task run data
- orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(true, nil).Run(func(args mock.Arguments) {
- run := args.Get(0).(*pipeline.Run)
+ orm.On("StoreRun", mock.Anything, mock.AnythingOfType("*pipeline.Run")).Return(true, nil).Run(func(args mock.Arguments) {
+ run := args.Get(1).(*pipeline.Run)
// Now simulate a new result coming in while we were running
task := run.ByDotID("ds1")
task.Error = null.NewString("", false)
@@ -816,7 +827,7 @@ ds5 [type=http method="GET" url="%s" index=2]
}
}).Once()
// StoreRun is called again to store the final result
- orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(false, nil).Once()
+ orm.On("StoreRun", mock.Anything, mock.AnythingOfType("*pipeline.Run")).Return(false, nil).Once()
incomplete, err := r.Run(testutils.Context(t), run, logger.TestLogger(t), false, nil)
require.NoError(t, err)
require.Len(t, run.PipelineTaskRuns, 12)
diff --git a/core/services/pipeline/task.bridge.go b/core/services/pipeline/task.bridge.go
index 1da34d19134..7995cf99296 100644
--- a/core/services/pipeline/task.bridge.go
+++ b/core/services/pipeline/task.bridge.go
@@ -109,7 +109,7 @@ func (t *BridgeTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inp
return Result{Error: errors.Errorf("headers must have an even number of elements")}, runInfo
}
- url, err := t.getBridgeURLFromName(name)
+ url, err := t.getBridgeURLFromName(ctx, name)
if err != nil {
return Result{Error: err}, runInfo
}
@@ -181,7 +181,7 @@ func (t *BridgeTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inp
}
var cacheErr error
- responseBytes, cacheErr = t.orm.GetCachedResponse(t.dotID, t.specId, cacheDuration)
+ responseBytes, cacheErr = t.orm.GetCachedResponse(ctx, t.dotID, t.specId, cacheDuration)
if cacheErr != nil {
promBridgeCacheErrors.WithLabelValues(t.Name).Inc()
if !errors.Is(cacheErr, sql.ErrNoRows) {
@@ -217,7 +217,7 @@ func (t *BridgeTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inp
}
if !cachedResponse && cacheTTL > 0 {
- err := t.orm.UpsertBridgeResponse(t.dotID, t.specId, responseBytes)
+ err := t.orm.UpsertBridgeResponse(ctx, t.dotID, t.specId, responseBytes)
if err != nil {
lggr.Errorw("Bridge task: failed to upsert response in bridge cache", "err", err)
}
@@ -241,8 +241,8 @@ func (t *BridgeTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inp
return result, runInfo
}
-func (t BridgeTask) getBridgeURLFromName(name StringParam) (URLParam, error) {
- bt, err := t.orm.FindBridge(bridges.BridgeName(name))
+func (t BridgeTask) getBridgeURLFromName(ctx context.Context, name StringParam) (URLParam, error) {
+ bt, err := t.orm.FindBridge(ctx, bridges.BridgeName(name))
if err != nil {
return URLParam{}, errors.Wrapf(err, "could not find bridge with name '%s'", name)
}
diff --git a/core/services/pipeline/task.bridge_test.go b/core/services/pipeline/task.bridge_test.go
index 7673add1e35..029c6c78ca8 100644
--- a/core/services/pipeline/task.bridge_test.go
+++ b/core/services/pipeline/task.bridge_test.go
@@ -207,8 +207,8 @@ func TestBridgeTask_Happy(t *testing.T) {
feedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
BaseTask: pipeline.NewBaseTask(0, "bridge", nil, nil, 0),
@@ -216,8 +216,8 @@ func TestBridgeTask_Happy(t *testing.T) {
RequestData: btcUSDPairing,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -248,8 +248,8 @@ func TestBridgeTask_HandlesIntermittentFailure(t *testing.T) {
feedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
BaseTask: pipeline.NewBaseTask(0, "bridge", nil, nil, 0),
@@ -258,8 +258,8 @@ func TestBridgeTask_HandlesIntermittentFailure(t *testing.T) {
CacheTTL: "30s", // standard duration string format
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
result, runInfo := task.Run(testutils.Context(t), logger.TestLogger(t),
@@ -312,8 +312,8 @@ func TestBridgeTask_DoesNotReturnStaleResults(t *testing.T) {
feedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
BaseTask: pipeline.NewBaseTask(0, "bridge", nil, nil, 0),
@@ -321,8 +321,8 @@ func TestBridgeTask_DoesNotReturnStaleResults(t *testing.T) {
RequestData: btcUSDPairing,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -472,8 +472,8 @@ func TestBridgeTask_AsyncJobPendingState(t *testing.T) {
feedURL, err := url.ParseRequestURI(server.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
Name: bridge.Name.String(),
@@ -481,8 +481,8 @@ func TestBridgeTask_AsyncJobPendingState(t *testing.T) {
Async: "true",
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, id, c)
@@ -649,8 +649,8 @@ func TestBridgeTask_Variables(t *testing.T) {
feedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
BaseTask: pipeline.NewBaseTask(0, "bridge", nil, nil, 0),
@@ -659,8 +659,8 @@ func TestBridgeTask_Variables(t *testing.T) {
IncludeInputAtKey: test.includeInputAtKey,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -719,8 +719,8 @@ func TestBridgeTask_Meta(t *testing.T) {
feedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
BaseTask: pipeline.NewBaseTask(0, "bridge", nil, nil, 0),
@@ -728,8 +728,8 @@ func TestBridgeTask_Meta(t *testing.T) {
Name: bridge.Name.String(),
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -772,8 +772,8 @@ func TestBridgeTask_IncludeInputAtKey(t *testing.T) {
feedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
BaseTask: pipeline.NewBaseTask(0, "bridge", nil, nil, 0),
@@ -782,8 +782,8 @@ func TestBridgeTask_IncludeInputAtKey(t *testing.T) {
IncludeInputAtKey: test.includeInputAtKey,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -830,16 +830,16 @@ func TestBridgeTask_ErrorMessage(t *testing.T) {
feedURL, err := url.ParseRequestURI(server.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
Name: bridge.Name.String(),
RequestData: ethUSDPairing,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -869,16 +869,16 @@ func TestBridgeTask_OnlyErrorMessage(t *testing.T) {
feedURL, err := url.ParseRequestURI(server.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
Name: bridge.Name.String(),
RequestData: ethUSDPairing,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -901,9 +901,9 @@ func TestBridgeTask_ErrorIfBridgeMissing(t *testing.T) {
RequestData: btcUSDPairing,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ orm := bridges.NewORM(db)
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -961,8 +961,8 @@ func TestBridgeTask_Headers(t *testing.T) {
bridgeURL, err := url.ParseRequestURI(server.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeURL.String()})
allHeaders := func(headers http.Header) (s []string) {
var keys []string
@@ -992,8 +992,8 @@ func TestBridgeTask_Headers(t *testing.T) {
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -1014,8 +1014,8 @@ func TestBridgeTask_Headers(t *testing.T) {
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -1036,8 +1036,8 @@ func TestBridgeTask_Headers(t *testing.T) {
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
@@ -1073,8 +1073,8 @@ func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) {
feedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
BaseTask: pipeline.NewBaseTask(0, "bridge", nil, nil, 0),
@@ -1082,8 +1082,8 @@ func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) {
RequestData: btcUSDPairing,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
diff --git a/core/services/pipeline/task.http_test.go b/core/services/pipeline/task.http_test.go
index d53e2247c68..6264d1e591b 100644
--- a/core/services/pipeline/task.http_test.go
+++ b/core/services/pipeline/task.http_test.go
@@ -24,7 +24,6 @@ import (
clhttptest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/httptest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
"github.com/smartcontractkit/chainlink/v2/core/utils"
@@ -168,8 +167,8 @@ func TestHTTPTask_Variables(t *testing.T) {
feedURL, err := url.ParseRequestURI(s1.URL)
require.NoError(t, err)
- orm := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
- _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}, cfg.Database())
+ orm := bridges.NewORM(db)
+ _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()})
task := pipeline.BridgeTask{
BaseTask: pipeline.NewBaseTask(0, "bridge", nil, nil, 0),
@@ -177,8 +176,8 @@ func TestHTTPTask_Variables(t *testing.T) {
RequestData: test.requestData,
}
c := clhttptest.NewTestLocalOnlyHTTPClient()
- trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- specID, err := trORM.CreateSpec(pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute), pg.WithParentCtx(testutils.Context(t)))
+ trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns())
+ specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute))
require.NoError(t, err)
task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c)
diff --git a/core/services/pipeline/test_helpers_test.go b/core/services/pipeline/test_helpers_test.go
index 3b72a1625be..fc87942e073 100644
--- a/core/services/pipeline/test_helpers_test.go
+++ b/core/services/pipeline/test_helpers_test.go
@@ -47,7 +47,7 @@ func makeBridge(t *testing.T, db *sqlx.DB, expectedRequest, response interface{}
bridgeFeedURL, err := url.ParseRequestURI(server.URL)
require.NoError(t, err)
- _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()}, cfg)
+ _, bt := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: bridgeFeedURL.String()})
return server, *bt
}
diff --git a/core/services/relay/evm/cap_encoder.go b/core/services/relay/evm/cap_encoder.go
index 1c7814ab16a..b52cbb71c66 100644
--- a/core/services/relay/evm/cap_encoder.go
+++ b/core/services/relay/evm/cap_encoder.go
@@ -87,8 +87,8 @@ func decodeID(input map[string]any, key string) ([]byte, error) {
return nil, err
}
- if len(b) < 32 {
- return nil, fmt.Errorf("incorrect length for id %s, expected 32 bytes, got %d", id, len(b))
+ if len(b) != idLen {
+ return nil, fmt.Errorf("incorrect length for id %s, expected %d bytes, got %d", id, idLen, len(b))
}
return b, nil
diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go
index 95cf9efc944..4f31110fda1 100644
--- a/core/services/relay/evm/evm.go
+++ b/core/services/relay/evm/evm.go
@@ -130,8 +130,8 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R
}
lggr = lggr.Named("Relayer")
- mercuryORM := mercury.NewORM(opts.DB, lggr, opts.QConfig)
- lloORM := llo.NewORM(pg.NewQ(opts.DB, lggr, opts.QConfig), chain.ID())
+ mercuryORM := mercury.NewORM(opts.DS)
+ lloORM := llo.NewORM(opts.DS, chain.ID())
cdcFactory := llo.NewChannelDefinitionCacheFactory(lggr, lloORM, chain.LogPoller())
return &Relayer{
db: opts.DB,
@@ -521,7 +521,7 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg
subject = *opts.subjectID
}
scoped := configWatcher.chain.Config()
- strategy := txmgrcommon.NewQueueingTxStrategy(subject, scoped.OCR2().DefaultTransactionQueueDepth(), scoped.Database().DefaultQueryTimeout())
+ strategy := txmgrcommon.NewQueueingTxStrategy(subject, scoped.OCR2().DefaultTransactionQueueDepth())
var checker txm.TransmitCheckerSpec
if configWatcher.chain.Config().OCR2().SimulateTransactions() {
diff --git a/core/services/relay/evm/functions.go b/core/services/relay/evm/functions.go
index ed7b247f46b..9444ab4164d 100644
--- a/core/services/relay/evm/functions.go
+++ b/core/services/relay/evm/functions.go
@@ -183,7 +183,7 @@ func newFunctionsContractTransmitter(ctx context.Context, contractVersion uint32
}
scoped := configWatcher.chain.Config()
- strategy := txmgrcommon.NewQueueingTxStrategy(rargs.ExternalJobID, scoped.OCR2().DefaultTransactionQueueDepth(), scoped.Database().DefaultQueryTimeout())
+ strategy := txmgrcommon.NewQueueingTxStrategy(rargs.ExternalJobID, scoped.OCR2().DefaultTransactionQueueDepth())
var checker txm.TransmitCheckerSpec
if configWatcher.chain.Config().OCR2().SimulateTransactions() {
diff --git a/core/services/relay/evm/mercury/orm.go b/core/services/relay/evm/mercury/orm.go
index 19f2aa8e16b..6426ef54a5d 100644
--- a/core/services/relay/evm/mercury/orm.go
+++ b/core/services/relay/evm/mercury/orm.go
@@ -8,24 +8,22 @@ import (
"sync"
"github.com/ethereum/go-ethereum/common"
- "github.com/jmoiron/sqlx"
"github.com/lib/pq"
pkgerrors "github.com/pkg/errors"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb"
)
type ORM interface {
- InsertTransmitRequest(serverURL string, req *pb.TransmitRequest, jobID int32, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error
- DeleteTransmitRequests(serverURL string, reqs []*pb.TransmitRequest, qopts ...pg.QOpt) error
- GetTransmitRequests(serverURL string, jobID int32, qopts ...pg.QOpt) ([]*Transmission, error)
- PruneTransmitRequests(serverURL string, jobID int32, maxSize int, qopts ...pg.QOpt) error
- LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error)
+ InsertTransmitRequest(ctx context.Context, serverURL string, req *pb.TransmitRequest, jobID int32, reportCtx ocrtypes.ReportContext) error
+ DeleteTransmitRequests(ctx context.Context, serverURL string, reqs []*pb.TransmitRequest) error
+ GetTransmitRequests(ctx context.Context, serverURL string, jobID int32) ([]*Transmission, error)
+ PruneTransmitRequests(ctx context.Context, serverURL string, jobID int32, maxSize int) error
+ LatestReport(ctx context.Context, feedID [32]byte) (report []byte, err error)
}
func FeedIDFromReport(report ocrtypes.Report) (feedID utils.FeedID, err error) {
@@ -36,32 +34,27 @@ func FeedIDFromReport(report ocrtypes.Report) (feedID utils.FeedID, err error) {
}
type orm struct {
- q pg.Q
+ ds sqlutil.DataSource
}
-func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) ORM {
- namedLogger := lggr.Named("MercuryORM")
- q := pg.NewQ(db, namedLogger, cfg)
- return &orm{
- q: q,
- }
+func NewORM(ds sqlutil.DataSource) ORM {
+ return &orm{ds: ds}
}
// InsertTransmitRequest inserts one transmit request if the payload does not exist already.
-func (o *orm) InsertTransmitRequest(serverURL string, req *pb.TransmitRequest, jobID int32, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error {
+func (o *orm) InsertTransmitRequest(ctx context.Context, serverURL string, req *pb.TransmitRequest, jobID int32, reportCtx ocrtypes.ReportContext) error {
feedID, err := FeedIDFromReport(req.Payload)
if err != nil {
return err
}
- q := o.q.WithOpts(qopts...)
var wg sync.WaitGroup
wg.Add(2)
var err1, err2 error
go func() {
defer wg.Done()
- err1 = q.ExecQ(`
+ _, err1 = o.ds.ExecContext(ctx, `
INSERT INTO mercury_transmit_requests (server_url, payload, payload_hash, config_digest, epoch, round, extra_hash, job_id, feed_id)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
ON CONFLICT (server_url, payload_hash) DO NOTHING
@@ -70,7 +63,7 @@ func (o *orm) InsertTransmitRequest(serverURL string, req *pb.TransmitRequest, j
go func() {
defer wg.Done()
- err2 = q.ExecQ(`
+ _, err2 = o.ds.ExecContext(ctx, `
INSERT INTO feed_latest_reports (feed_id, report, epoch, round, updated_at, job_id)
VALUES ($1, $2, $3, $4, NOW(), $5)
ON CONFLICT (feed_id) DO UPDATE
@@ -83,7 +76,7 @@ func (o *orm) InsertTransmitRequest(serverURL string, req *pb.TransmitRequest, j
}
// DeleteTransmitRequest deletes the given transmit requests if they exist.
-func (o *orm) DeleteTransmitRequests(serverURL string, reqs []*pb.TransmitRequest, qopts ...pg.QOpt) error {
+func (o *orm) DeleteTransmitRequests(ctx context.Context, serverURL string, reqs []*pb.TransmitRequest) error {
if len(reqs) == 0 {
return nil
}
@@ -93,8 +86,7 @@ func (o *orm) DeleteTransmitRequests(serverURL string, reqs []*pb.TransmitReques
hashes = append(hashes, hashPayload(req.Payload))
}
- q := o.q.WithOpts(qopts...)
- err := q.ExecQ(`
+ _, err := o.ds.ExecContext(ctx, `
DELETE FROM mercury_transmit_requests
WHERE server_url = $1 AND payload_hash = ANY($2)
`, serverURL, hashes)
@@ -102,11 +94,10 @@ func (o *orm) DeleteTransmitRequests(serverURL string, reqs []*pb.TransmitReques
}
// GetTransmitRequests returns all transmit requests in chronologically descending order.
-func (o *orm) GetTransmitRequests(serverURL string, jobID int32, qopts ...pg.QOpt) ([]*Transmission, error) {
- q := o.q.WithOpts(qopts...)
+func (o *orm) GetTransmitRequests(ctx context.Context, serverURL string, jobID int32) ([]*Transmission, error) {
// The priority queue uses epoch and round to sort transmissions so order by
// the same fields here for optimal insertion into the pq.
- rows, err := q.QueryContext(q.ParentCtx, `
+ rows, err := o.ds.QueryContext(ctx, `
SELECT payload, config_digest, epoch, round, extra_hash
FROM mercury_transmit_requests
WHERE job_id = $1 AND server_url = $2
@@ -146,10 +137,9 @@ func (o *orm) GetTransmitRequests(serverURL string, jobID int32, qopts ...pg.QOp
// PruneTransmitRequests keeps at most maxSize rows for the given job ID,
// deleting the oldest transactions.
-func (o *orm) PruneTransmitRequests(serverURL string, jobID int32, maxSize int, qopts ...pg.QOpt) error {
- q := o.q.WithOpts(qopts...)
+func (o *orm) PruneTransmitRequests(ctx context.Context, serverURL string, jobID int32, maxSize int) error {
// Prune the oldest requests by epoch and round.
- return q.ExecQ(`
+ _, err := o.ds.ExecContext(ctx, `
DELETE FROM mercury_transmit_requests
WHERE job_id = $1 AND server_url = $2 AND
payload_hash NOT IN (
@@ -160,11 +150,11 @@ func (o *orm) PruneTransmitRequests(serverURL string, jobID int32, maxSize int,
LIMIT $3
)
`, jobID, serverURL, maxSize)
+ return err
}
-func (o *orm) LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) {
- q := o.q.WithOpts(qopts...)
- err = q.GetContext(ctx, &report, `SELECT report FROM feed_latest_reports WHERE feed_id = $1`, feedID[:])
+func (o *orm) LatestReport(ctx context.Context, feedID [32]byte) (report []byte, err error) {
+ err = o.ds.GetContext(ctx, &report, `SELECT report FROM feed_latest_reports WHERE feed_id = $1`, feedID[:])
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
diff --git a/core/services/relay/evm/mercury/orm_test.go b/core/services/relay/evm/mercury/orm_test.go
index 14be878eeef..2b2e15ffd53 100644
--- a/core/services/relay/evm/mercury/orm_test.go
+++ b/core/services/relay/evm/mercury/orm_test.go
@@ -10,7 +10,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb"
)
@@ -21,13 +20,13 @@ var (
)
func TestORM(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
jobID := rand.Int32() // foreign key constraints disabled so value doesn't matter
pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
- lggr := logger.TestLogger(t)
- orm := NewORM(db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(db)
feedID := sampleFeedID
reports := sampleReports
@@ -49,25 +48,25 @@ func TestORM(t *testing.T) {
// Test insert and get requests.
// s1
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[0]}, jobID, reportContexts[0])
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[0]}, jobID, reportContexts[0])
require.NoError(t, err)
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[1]}, jobID, reportContexts[1])
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[1]}, jobID, reportContexts[1])
require.NoError(t, err)
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[2]}, jobID, reportContexts[2])
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[2]}, jobID, reportContexts[2])
require.NoError(t, err)
// s2
- err = orm.InsertTransmitRequest(sURL2, &pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[0])
+ err = orm.InsertTransmitRequest(ctx, sURL2, &pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[0])
require.NoError(t, err)
- transmissions, err := orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err := orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, transmissions, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[2]}, ReportCtx: reportContexts[2]},
{Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: reportContexts[1]},
{Req: &pb.TransmitRequest{Payload: reports[0]}, ReportCtx: reportContexts[0]},
})
- transmissions, err = orm.GetTransmitRequests(sURL2, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL2, jobID)
require.NoError(t, err)
require.Equal(t, transmissions, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[3]}, ReportCtx: reportContexts[0]},
@@ -79,10 +78,10 @@ func TestORM(t *testing.T) {
assert.Equal(t, reports[2], l)
// Test requests can be deleted.
- err = orm.DeleteTransmitRequests(sURL, []*pb.TransmitRequest{{Payload: reports[1]}})
+ err = orm.DeleteTransmitRequests(ctx, sURL, []*pb.TransmitRequest{{Payload: reports[1]}})
require.NoError(t, err)
- transmissions, err = orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, transmissions, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[2]}, ReportCtx: reportContexts[2]},
@@ -94,10 +93,10 @@ func TestORM(t *testing.T) {
assert.Equal(t, reports[2], l)
// Test deleting non-existent requests does not error.
- err = orm.DeleteTransmitRequests(sURL, []*pb.TransmitRequest{{Payload: []byte("does-not-exist")}})
+ err = orm.DeleteTransmitRequests(ctx, sURL, []*pb.TransmitRequest{{Payload: []byte("does-not-exist")}})
require.NoError(t, err)
- transmissions, err = orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, transmissions, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[2]}, ReportCtx: reportContexts[2]},
@@ -105,7 +104,7 @@ func TestORM(t *testing.T) {
})
// Test deleting multiple requests.
- err = orm.DeleteTransmitRequests(sURL, []*pb.TransmitRequest{
+ err = orm.DeleteTransmitRequests(ctx, sURL, []*pb.TransmitRequest{
{Payload: reports[0]},
{Payload: reports[2]},
})
@@ -115,27 +114,27 @@ func TestORM(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, reports[2], l)
- transmissions, err = orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Empty(t, transmissions)
// More inserts.
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
require.NoError(t, err)
- transmissions, err = orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, transmissions, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[3]}, ReportCtx: reportContexts[3]},
})
// Duplicate requests are ignored.
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
require.NoError(t, err)
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
require.NoError(t, err)
- transmissions, err = orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, transmissions, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[3]}, ReportCtx: reportContexts[3]},
@@ -146,20 +145,20 @@ func TestORM(t *testing.T) {
assert.Equal(t, reports[3], l)
// s2 not affected by deletion
- transmissions, err = orm.GetTransmitRequests(sURL2, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL2, jobID)
require.NoError(t, err)
require.Len(t, transmissions, 1)
}
func TestORM_PruneTransmitRequests(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
jobID := rand.Int32() // foreign key constraints disabled so value doesn't matter
pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
- lggr := logger.TestLogger(t)
- orm := NewORM(db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(db)
reports := sampleReports
@@ -175,25 +174,25 @@ func TestORM_PruneTransmitRequests(t *testing.T) {
}
// s1
- err := orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(1, 1))
+ err := orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(1, 1))
require.NoError(t, err)
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(1, 2))
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(1, 2))
require.NoError(t, err)
// s2 - should not be touched
- err = orm.InsertTransmitRequest(sURL2, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(1, 0))
+ err = orm.InsertTransmitRequest(ctx, sURL2, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(1, 0))
require.NoError(t, err)
- err = orm.InsertTransmitRequest(sURL2, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(1, 1))
+ err = orm.InsertTransmitRequest(ctx, sURL2, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(1, 1))
require.NoError(t, err)
- err = orm.InsertTransmitRequest(sURL2, &pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(1, 2))
+ err = orm.InsertTransmitRequest(ctx, sURL2, &pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(1, 2))
require.NoError(t, err)
- err = orm.InsertTransmitRequest(sURL2, &pb.TransmitRequest{Payload: reports[2]}, jobID, makeReportContext(1, 3))
+ err = orm.InsertTransmitRequest(ctx, sURL2, &pb.TransmitRequest{Payload: reports[2]}, jobID, makeReportContext(1, 3))
require.NoError(t, err)
// Max size greater than number of records, expect no-op
- err = orm.PruneTransmitRequests(sURL, jobID, 5)
+ err = orm.PruneTransmitRequests(ctx, sURL, jobID, 5)
require.NoError(t, err)
- transmissions, err := orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err := orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, transmissions, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: makeReportContext(1, 2)},
@@ -201,10 +200,10 @@ func TestORM_PruneTransmitRequests(t *testing.T) {
})
// Max size equal to number of records, expect no-op
- err = orm.PruneTransmitRequests(sURL, jobID, 2)
+ err = orm.PruneTransmitRequests(ctx, sURL, jobID, 2)
require.NoError(t, err)
- transmissions, err = orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, transmissions, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: makeReportContext(1, 2)},
@@ -212,26 +211,26 @@ func TestORM_PruneTransmitRequests(t *testing.T) {
})
// Max size is number of records + 1, but jobID differs, expect no-op
- err = orm.PruneTransmitRequests(sURL, -1, 2)
+ err = orm.PruneTransmitRequests(ctx, sURL, -1, 2)
require.NoError(t, err)
- transmissions, err = orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[1]}, ReportCtx: makeReportContext(1, 2)},
{Req: &pb.TransmitRequest{Payload: reports[0]}, ReportCtx: makeReportContext(1, 1)},
}, transmissions)
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[2]}, jobID, makeReportContext(2, 1))
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[2]}, jobID, makeReportContext(2, 1))
require.NoError(t, err)
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[3]}, jobID, makeReportContext(2, 2))
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[3]}, jobID, makeReportContext(2, 2))
require.NoError(t, err)
// Max size is table size - 1, expect the oldest row to be pruned.
- err = orm.PruneTransmitRequests(sURL, jobID, 3)
+ err = orm.PruneTransmitRequests(ctx, sURL, jobID, 3)
require.NoError(t, err)
- transmissions, err = orm.GetTransmitRequests(sURL, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL, jobID)
require.NoError(t, err)
require.Equal(t, []*Transmission{
{Req: &pb.TransmitRequest{Payload: reports[3]}, ReportCtx: makeReportContext(2, 2)},
@@ -240,19 +239,19 @@ func TestORM_PruneTransmitRequests(t *testing.T) {
}, transmissions)
// s2 not touched
- transmissions, err = orm.GetTransmitRequests(sURL2, jobID)
+ transmissions, err = orm.GetTransmitRequests(ctx, sURL2, jobID)
require.NoError(t, err)
assert.Len(t, transmissions, 3)
}
func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
jobID := rand.Int32() // foreign key constraints disabled so value doesn't matter
pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
- lggr := logger.TestLogger(t)
- orm := NewORM(db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(db)
feedID := sampleFeedID
reports := sampleReports
@@ -268,13 +267,13 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
}
}
- err := orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(
+ err := orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(
0, 0,
))
require.NoError(t, err)
// this should be ignored, because report context is the same
- err = orm.InsertTransmitRequest(sURL2, &pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(
+ err = orm.InsertTransmitRequest(ctx, sURL2, &pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(
0, 0,
))
require.NoError(t, err)
@@ -284,7 +283,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
assert.Equal(t, reports[0], l)
t.Run("replaces if epoch and round are larger", func(t *testing.T) {
- err = orm.InsertTransmitRequest("foo", &pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(1, 1))
+ err = orm.InsertTransmitRequest(ctx, "foo", &pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(1, 1))
require.NoError(t, err)
l, err = orm.LatestReport(testutils.Context(t), feedID)
@@ -292,7 +291,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
assert.Equal(t, reports[1], l)
})
t.Run("replaces if epoch is the same but round is greater", func(t *testing.T) {
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[2]}, jobID, makeReportContext(1, 2))
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[2]}, jobID, makeReportContext(1, 2))
require.NoError(t, err)
l, err = orm.LatestReport(testutils.Context(t), feedID)
@@ -300,7 +299,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
assert.Equal(t, reports[2], l)
})
t.Run("replaces if epoch is larger but round is smaller", func(t *testing.T) {
- err = orm.InsertTransmitRequest("bar", &pb.TransmitRequest{Payload: reports[3]}, jobID, makeReportContext(2, 1))
+ err = orm.InsertTransmitRequest(ctx, "bar", &pb.TransmitRequest{Payload: reports[3]}, jobID, makeReportContext(2, 1))
require.NoError(t, err)
l, err = orm.LatestReport(testutils.Context(t), feedID)
@@ -308,7 +307,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
assert.Equal(t, reports[3], l)
})
t.Run("does not overwrite if epoch/round is the same", func(t *testing.T) {
- err = orm.InsertTransmitRequest(sURL, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(2, 1))
+ err = orm.InsertTransmitRequest(ctx, sURL, &pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(2, 1))
require.NoError(t, err)
l, err = orm.LatestReport(testutils.Context(t), feedID)
diff --git a/core/services/relay/evm/mercury/persistence_manager.go b/core/services/relay/evm/mercury/persistence_manager.go
index dc805c12e7b..d49d0d4ed01 100644
--- a/core/services/relay/evm/mercury/persistence_manager.go
+++ b/core/services/relay/evm/mercury/persistence_manager.go
@@ -8,8 +8,8 @@ import (
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -69,11 +69,11 @@ func (pm *PersistenceManager) Close() error {
}
func (pm *PersistenceManager) Insert(ctx context.Context, req *pb.TransmitRequest, reportCtx ocrtypes.ReportContext) error {
- return pm.orm.InsertTransmitRequest(pm.serverURL, req, pm.jobID, reportCtx, pg.WithParentCtx(ctx))
+ return pm.orm.InsertTransmitRequest(ctx, pm.serverURL, req, pm.jobID, reportCtx)
}
func (pm *PersistenceManager) Delete(ctx context.Context, req *pb.TransmitRequest) error {
- return pm.orm.DeleteTransmitRequests(pm.serverURL, []*pb.TransmitRequest{req}, pg.WithParentCtx(ctx))
+ return pm.orm.DeleteTransmitRequests(ctx, pm.serverURL, []*pb.TransmitRequest{req})
}
func (pm *PersistenceManager) AsyncDelete(req *pb.TransmitRequest) {
@@ -81,7 +81,7 @@ func (pm *PersistenceManager) AsyncDelete(req *pb.TransmitRequest) {
}
func (pm *PersistenceManager) Load(ctx context.Context) ([]*Transmission, error) {
- return pm.orm.GetTransmitRequests(pm.serverURL, pm.jobID, pg.WithParentCtx(ctx))
+ return pm.orm.GetTransmitRequests(ctx, pm.serverURL, pm.jobID)
}
func (pm *PersistenceManager) runFlushDeletesLoop() {
@@ -98,7 +98,7 @@ func (pm *PersistenceManager) runFlushDeletesLoop() {
return
case <-ticker.C:
queuedReqs := pm.resetDeleteQueue()
- if err := pm.orm.DeleteTransmitRequests(pm.serverURL, queuedReqs, pg.WithParentCtx(ctx)); err != nil {
+ if err := pm.orm.DeleteTransmitRequests(ctx, pm.serverURL, queuedReqs); err != nil {
pm.lggr.Errorw("Failed to delete queued transmit requests", "err", err)
pm.addToDeleteQueue(queuedReqs...)
} else {
@@ -111,7 +111,7 @@ func (pm *PersistenceManager) runFlushDeletesLoop() {
func (pm *PersistenceManager) runPruneLoop() {
defer pm.wg.Done()
- ctx, cancel := pm.stopCh.Ctx(context.Background())
+ ctx, cancel := pm.stopCh.NewCtx()
defer cancel()
ticker := time.NewTicker(utils.WithJitter(pm.pruneFrequency))
@@ -121,11 +121,15 @@ func (pm *PersistenceManager) runPruneLoop() {
ticker.Stop()
return
case <-ticker.C:
- if err := pm.orm.PruneTransmitRequests(pm.serverURL, pm.jobID, pm.maxTransmitQueueSize, pg.WithParentCtx(ctx), pg.WithLongQueryTimeout()); err != nil {
- pm.lggr.Errorw("Failed to prune transmit requests table", "err", err)
- } else {
- pm.lggr.Debugw("Pruned transmit requests table")
- }
+ func(ctx context.Context) {
+ ctx, cancelPrune := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute)
+ defer cancelPrune()
+ if err := pm.orm.PruneTransmitRequests(ctx, pm.serverURL, pm.jobID, pm.maxTransmitQueueSize); err != nil {
+ pm.lggr.Errorw("Failed to prune transmit requests table", "err", err)
+ } else {
+ pm.lggr.Debugw("Pruned transmit requests table")
+ }
+ }(ctx)
}
}
}
diff --git a/core/services/relay/evm/mercury/persistence_manager_test.go b/core/services/relay/evm/mercury/persistence_manager_test.go
index 15b1424f1a4..1ba999614a6 100644
--- a/core/services/relay/evm/mercury/persistence_manager_test.go
+++ b/core/services/relay/evm/mercury/persistence_manager_test.go
@@ -22,7 +22,7 @@ import (
func bootstrapPersistenceManager(t *testing.T, jobID int32, db *sqlx.DB) (*PersistenceManager, *observer.ObservedLogs) {
t.Helper()
lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel)
- orm := NewORM(db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(db)
return NewPersistenceManager(lggr, "mercuryserver.example", orm, jobID, 2, 5*time.Millisecond, 5*time.Millisecond), observedLogs
}
diff --git a/core/services/relay/evm/mercury/transmitter_test.go b/core/services/relay/evm/mercury/transmitter_test.go
index d7d62a9f422..46bf116ed3a 100644
--- a/core/services/relay/evm/mercury/transmitter_test.go
+++ b/core/services/relay/evm/mercury/transmitter_test.go
@@ -17,7 +17,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc"
- mocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/mocks"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb"
)
@@ -28,7 +28,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) {
pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
codec := new(mockCodec)
- orm := NewORM(db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(db)
clients := map[string]wsrpc.Client{}
t.Run("with one mercury server", func(t *testing.T) {
@@ -109,7 +109,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) {
var jobID int32
codec := new(mockCodec)
- orm := NewORM(db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(db)
clients := map[string]wsrpc.Client{}
t.Run("successful query", func(t *testing.T) {
@@ -211,7 +211,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) {
var jobID int32
codec := new(mockCodec)
- orm := NewORM(db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(db)
clients := map[string]wsrpc.Client{}
t.Run("successful query", func(t *testing.T) {
@@ -287,7 +287,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) {
db := pgtest.NewSqlxDB(t)
var jobID int32
codec := new(mockCodec)
- orm := NewORM(db, lggr, pgtest.NewQConfig(true))
+ orm := NewORM(db)
clients := map[string]wsrpc.Client{}
t.Run("successful query", func(t *testing.T) {
diff --git a/core/services/relay/evm/mercury/types/types.go b/core/services/relay/evm/mercury/types/types.go
index 49bffb6c290..972367940b5 100644
--- a/core/services/relay/evm/mercury/types/types.go
+++ b/core/services/relay/evm/mercury/types/types.go
@@ -7,12 +7,10 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
-
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
type DataSourceORM interface {
- LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error)
+ LatestReport(ctx context.Context, feedID [32]byte) (report []byte, err error)
}
type ReportCodec interface {
diff --git a/core/services/relay/evm/mercury/v1/data_source_test.go b/core/services/relay/evm/mercury/v1/data_source_test.go
index e0769fe5b64..197d802a3b3 100644
--- a/core/services/relay/evm/mercury/v1/data_source_test.go
+++ b/core/services/relay/evm/mercury/v1/data_source_test.go
@@ -18,14 +18,13 @@ import (
mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury"
v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1"
- commonmocks "github.com/smartcontractkit/chainlink/v2/common/mocks"
+ htmocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks"
@@ -65,7 +64,7 @@ type mockORM struct {
err error
}
-func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) {
+func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte) (report []byte, err error) {
return m.report, m.err
}
@@ -117,7 +116,7 @@ func TestMercury_Observe(t *testing.T) {
spec := pipeline.Spec{}
ds.spec = spec
- h := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
+ h := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
ds.mercuryChainReader = evm.NewMercuryChainReader(h)
head := &evmtypes.Head{
@@ -208,7 +207,7 @@ func TestMercury_Observe(t *testing.T) {
assert.Equal(t, head.Number-1, obs.MaxFinalizedBlockNumber.Val)
})
t.Run("if no current block available", func(t *testing.T) {
- h2 := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
+ h2 := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
h2.On("LatestChain").Return((*evmtypes.Head)(nil))
ds.mercuryChainReader = evm.NewMercuryChainReader(h2)
@@ -319,7 +318,7 @@ func TestMercury_Observe(t *testing.T) {
t.Run("LatestBlocks is populated correctly", func(t *testing.T) {
t.Run("when chain length is zero", func(t *testing.T) {
- ht2 := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
+ ht2 := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
ht2.On("LatestChain").Return((*evmtypes.Head)(nil))
ds.mercuryChainReader = evm.NewMercuryChainReader(ht2)
@@ -344,7 +343,7 @@ func TestMercury_Observe(t *testing.T) {
Parent: h5,
}
- ht2 := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
+ ht2 := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
ht2.On("LatestChain").Return(h6)
ds.mercuryChainReader = evm.NewMercuryChainReader(ht2)
@@ -367,7 +366,7 @@ func TestMercury_Observe(t *testing.T) {
}
}
- ht2 := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
+ ht2 := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
ht2.On("LatestChain").Return(heads[len(heads)-1])
ds.mercuryChainReader = evm.NewMercuryChainReader(ht2)
@@ -412,7 +411,7 @@ func TestMercury_SetLatestBlocks(t *testing.T) {
}
t.Run("returns head from headtracker if present", func(t *testing.T) {
- headTracker := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
+ headTracker := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
headTracker.On("LatestChain").Return(&h, nil)
ds.mercuryChainReader = evm.NewMercuryChainReader(headTracker)
@@ -429,7 +428,7 @@ func TestMercury_SetLatestBlocks(t *testing.T) {
})
t.Run("if headtracker returns nil head", func(t *testing.T) {
- headTracker := commonmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
+ headTracker := htmocks.NewHeadTracker[*evmtypes.Head, common.Hash](t)
// This can happen in some cases e.g. RPC node is offline
headTracker.On("LatestChain").Return((*evmtypes.Head)(nil))
ds.mercuryChainReader = evm.NewChainReader(headTracker)
diff --git a/core/services/relay/evm/mercury/v2/data_source_test.go b/core/services/relay/evm/mercury/v2/data_source_test.go
index c9ae37ae018..19af909c8e9 100644
--- a/core/services/relay/evm/mercury/v2/data_source_test.go
+++ b/core/services/relay/evm/mercury/v2/data_source_test.go
@@ -15,7 +15,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
@@ -59,7 +58,7 @@ type mockORM struct {
err error
}
-func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) {
+func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte) (report []byte, err error) {
return m.report, m.err
}
diff --git a/core/services/relay/evm/mercury/v3/data_source_test.go b/core/services/relay/evm/mercury/v3/data_source_test.go
index 4ff713abb21..ffcdc28f81c 100644
--- a/core/services/relay/evm/mercury/v3/data_source_test.go
+++ b/core/services/relay/evm/mercury/v3/data_source_test.go
@@ -15,7 +15,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
@@ -59,7 +58,7 @@ type mockORM struct {
err error
}
-func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) {
+func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte) (report []byte, err error) {
return m.report, m.err
}
diff --git a/core/services/relay/evm/mocks/request_round_db.go b/core/services/relay/evm/mocks/request_round_db.go
index 725fc6e6b37..4168ba4a1b0 100644
--- a/core/services/relay/evm/mocks/request_round_db.go
+++ b/core/services/relay/evm/mocks/request_round_db.go
@@ -9,6 +9,8 @@ import (
mock "github.com/stretchr/testify/mock"
ocr2aggregator "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator"
+
+ sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
)
// RequestRoundDB is an autogenerated mock type for the RequestRoundDB type
@@ -62,19 +64,21 @@ func (_m *RequestRoundDB) SaveLatestRoundRequested(ctx context.Context, rr ocr2a
return r0
}
-// Transact provides a mock function with given fields: _a0, _a1
-func (_m *RequestRoundDB) Transact(_a0 context.Context, _a1 func(evm.RequestRoundDB) error) error {
- ret := _m.Called(_a0, _a1)
+// WithDataSource provides a mock function with given fields: _a0
+func (_m *RequestRoundDB) WithDataSource(_a0 sqlutil.DataSource) evm.RequestRoundDB {
+ ret := _m.Called(_a0)
if len(ret) == 0 {
- panic("no return value specified for Transact")
+ panic("no return value specified for WithDataSource")
}
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, func(evm.RequestRoundDB) error) error); ok {
- r0 = rf(_a0, _a1)
+ var r0 evm.RequestRoundDB
+ if rf, ok := ret.Get(0).(func(sqlutil.DataSource) evm.RequestRoundDB); ok {
+ r0 = rf(_a0)
} else {
- r0 = ret.Error(0)
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(evm.RequestRoundDB)
+ }
}
return r0
diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go
index 742bab3a696..0dd971123c6 100644
--- a/core/services/relay/evm/ocr2keeper.go
+++ b/core/services/relay/evm/ocr2keeper.go
@@ -6,7 +6,6 @@ import (
"fmt"
"github.com/ethereum/go-ethereum/common"
- "github.com/jmoiron/sqlx"
"github.com/pkg/errors"
"github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil"
@@ -14,6 +13,7 @@ import (
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
commontypes "github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/smartcontractkit/chainlink-common/pkg/types/automation"
@@ -65,7 +65,7 @@ type OCR2KeeperRelayer interface {
// ocr2keeperRelayer is the relayer with added DKG and OCR2Keeper provider functions.
type ocr2keeperRelayer struct {
- db *sqlx.DB
+ ds sqlutil.DataSource
chain legacyevm.Chain
lggr logger.Logger
ethKeystore keystore.Eth
@@ -73,9 +73,9 @@ type ocr2keeperRelayer struct {
}
// NewOCR2KeeperRelayer is the constructor of ocr2keeperRelayer
-func NewOCR2KeeperRelayer(db *sqlx.DB, chain legacyevm.Chain, lggr logger.Logger, ethKeystore keystore.Eth, dbCfg pg.QConfig) OCR2KeeperRelayer {
+func NewOCR2KeeperRelayer(ds sqlutil.DataSource, chain legacyevm.Chain, lggr logger.Logger, ethKeystore keystore.Eth, dbCfg pg.QConfig) OCR2KeeperRelayer {
return &ocr2keeperRelayer{
- db: db,
+ ds: ds,
chain: chain,
lggr: lggr,
ethKeystore: ethKeystore,
@@ -126,7 +126,7 @@ func (r *ocr2keeperRelayer) NewOCR2KeeperProvider(rargs commontypes.RelayArgs, p
finalityDepth := client.Config().EVM().FinalityDepth()
- orm := upkeepstate.NewORM(client.ID(), r.db, r.lggr, r.dbCfg)
+ orm := upkeepstate.NewORM(client.ID(), r.ds)
scanner := upkeepstate.NewPerformedEventsScanner(r.lggr, client.LogPoller(), addr, finalityDepth)
services.upkeepStateStore = upkeepstate.NewUpkeepStateStore(orm, r.lggr, scanner)
diff --git a/core/services/relay/evm/request_round_db.go b/core/services/relay/evm/request_round_db.go
index 2b6ae10782d..96c5a05d1c7 100644
--- a/core/services/relay/evm/request_round_db.go
+++ b/core/services/relay/evm/request_round_db.go
@@ -12,16 +12,17 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
)
+//go:generate mockery --quiet --name RequestRoundDB --output ./mocks/ --case=underscore
+
// RequestRoundDB stores requested rounds for querying by the median plugin.
type RequestRoundDB interface {
SaveLatestRoundRequested(ctx context.Context, rr ocr2aggregator.OCR2AggregatorRoundRequested) error
LoadLatestRoundRequested(context.Context) (rr ocr2aggregator.OCR2AggregatorRoundRequested, err error)
- Transact(context.Context, func(db RequestRoundDB) error) error
+ WithDataSource(sqlutil.DataSource) RequestRoundDB
}
var _ RequestRoundDB = &requestRoundDB{}
-//go:generate mockery --quiet --name RequestRoundDB --output ./mocks/ --case=underscore
type requestRoundDB struct {
ds sqlutil.DataSource
oracleSpecID int32
@@ -33,10 +34,8 @@ func NewRoundRequestedDB(ds sqlutil.DataSource, oracleSpecID int32, lggr logger.
return &requestRoundDB{ds, oracleSpecID, lggr}
}
-func (d *requestRoundDB) Transact(ctx context.Context, fn func(db RequestRoundDB) error) error {
- return sqlutil.Transact(ctx, func(ds sqlutil.DataSource) RequestRoundDB {
- return NewRoundRequestedDB(ds, d.oracleSpecID, d.lggr)
- }, d.ds, nil, fn)
+func (d *requestRoundDB) WithDataSource(ds sqlutil.DataSource) RequestRoundDB {
+ return NewRoundRequestedDB(ds, d.oracleSpecID, d.lggr)
}
func (d *requestRoundDB) SaveLatestRoundRequested(ctx context.Context, rr ocr2aggregator.OCR2AggregatorRoundRequested) error {
diff --git a/core/services/relay/evm/request_round_db_test.go b/core/services/relay/evm/request_round_db_test.go
index 10932c4e229..26f8e2ac1a6 100644
--- a/core/services/relay/evm/request_round_db_test.go
+++ b/core/services/relay/evm/request_round_db_test.go
@@ -37,9 +37,7 @@ func Test_DB_LatestRoundRequested(t *testing.T) {
t.Run("saves latest round requested", func(t *testing.T) {
ctx := testutils.Context(t)
- err := db.Transact(ctx, func(tx evm.RequestRoundDB) error {
- return tx.SaveLatestRoundRequested(ctx, rr)
- })
+ err := db.SaveLatestRoundRequested(ctx, rr)
require.NoError(t, err)
rawLog.Index = 42
@@ -53,9 +51,7 @@ func Test_DB_LatestRoundRequested(t *testing.T) {
Raw: rawLog,
}
- err = db.Transact(ctx, func(tx evm.RequestRoundDB) error {
- return tx.SaveLatestRoundRequested(ctx, rr)
- })
+ err = db.SaveLatestRoundRequested(ctx, rr)
require.NoError(t, err)
})
diff --git a/core/services/relay/evm/request_round_tracker.go b/core/services/relay/evm/request_round_tracker.go
index bb39271f278..fe6b6826eb2 100644
--- a/core/services/relay/evm/request_round_tracker.go
+++ b/core/services/relay/evm/request_round_tracker.go
@@ -106,8 +106,8 @@ func (t *RequestRoundTracker) Close() error {
// HandleLog complies with LogListener interface
// It is not thread safe
-func (t *RequestRoundTracker) HandleLog(lb log.Broadcast) {
- was, err := t.logBroadcaster.WasAlreadyConsumed(t.ctx, lb)
+func (t *RequestRoundTracker) HandleLog(ctx context.Context, lb log.Broadcast) {
+ was, err := t.logBroadcaster.WasAlreadyConsumed(ctx, lb)
if err != nil {
t.lggr.Errorw("OCRContract: could not determine if log was already consumed", "err", err)
return
@@ -118,12 +118,12 @@ func (t *RequestRoundTracker) HandleLog(lb log.Broadcast) {
raw := lb.RawLog()
if raw.Address != t.contract.Address() {
t.lggr.Errorf("log address of 0x%x does not match configured contract address of 0x%x", raw.Address, t.contract.Address())
- t.lggr.ErrorIf(t.logBroadcaster.MarkConsumed(t.ctx, lb), "unable to mark consumed")
+ t.lggr.ErrorIf(t.logBroadcaster.MarkConsumed(ctx, nil, lb), "unable to mark consumed")
return
}
topics := raw.Topics
if len(topics) == 0 {
- t.lggr.ErrorIf(t.logBroadcaster.MarkConsumed(t.ctx, lb), "unable to mark consumed")
+ t.lggr.ErrorIf(t.logBroadcaster.MarkConsumed(ctx, nil, lb), "unable to mark consumed")
return
}
@@ -134,16 +134,15 @@ func (t *RequestRoundTracker) HandleLog(lb log.Broadcast) {
rr, err = t.contractFilterer.ParseRoundRequested(raw)
if err != nil {
t.lggr.Errorw("could not parse round requested", "err", err)
- t.lggr.ErrorIf(t.logBroadcaster.MarkConsumed(t.ctx, lb), "unable to mark consumed")
+ t.lggr.ErrorIf(t.logBroadcaster.MarkConsumed(ctx, nil, lb), "unable to mark consumed")
return
}
if IsLaterThan(raw, t.latestRoundRequested.Raw) {
- ctx := context.TODO() //TODO https://smartcontract-it.atlassian.net/browse/BCF-2887
- err = t.odb.Transact(ctx, func(tx RequestRoundDB) error {
- if err = tx.SaveLatestRoundRequested(ctx, *rr); err != nil {
+ err = sqlutil.TransactDataSource(ctx, t.ds, nil, func(tx sqlutil.DataSource) error {
+ if err = t.odb.WithDataSource(tx).SaveLatestRoundRequested(ctx, *rr); err != nil {
return err
}
- return t.logBroadcaster.MarkConsumed(t.ctx, lb)
+ return t.logBroadcaster.MarkConsumed(ctx, tx, lb)
})
if err != nil {
t.lggr.Error(err)
@@ -161,7 +160,7 @@ func (t *RequestRoundTracker) HandleLog(lb log.Broadcast) {
t.lggr.Debugw("RequestRoundTracker: got unrecognised log topic", "topic", topics[0])
}
if !consumed {
- t.lggr.ErrorIf(t.logBroadcaster.MarkConsumed(t.ctx, lb), "unable to mark consumed")
+ t.lggr.ErrorIf(t.logBroadcaster.MarkConsumed(ctx, nil, lb), "unable to mark consumed")
}
}
diff --git a/core/services/relay/evm/request_round_tracker_test.go b/core/services/relay/evm/request_round_tracker_test.go
index 324b76dc6de..3421004ccf5 100644
--- a/core/services/relay/evm/request_round_tracker_test.go
+++ b/core/services/relay/evm/request_round_tracker_test.go
@@ -14,7 +14,8 @@ import (
"github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
- commonmocks "github.com/smartcontractkit/chainlink/v2/common/mocks"
+ "github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
+ htmocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks"
evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
logmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks"
@@ -46,7 +47,7 @@ func mustNewFilterer(t *testing.T, address gethCommon.Address) *ocr2aggregator.O
type contractTrackerUni struct {
db *mocks.RequestRoundDB
lb *logmocks.Broadcaster
- hb *commonmocks.HeadBroadcaster[*evmtypes.Head, common.Hash]
+ hb *htmocks.HeadBroadcaster[*evmtypes.Head, common.Hash]
ec *evmclimocks.Client
requestRoundTracker *evm.RequestRoundTracker
}
@@ -78,7 +79,7 @@ func newContractTrackerUni(t *testing.T, opts ...interface{}) (uni contractTrack
}
uni.db = mocks.NewRequestRoundDB(t)
uni.lb = logmocks.NewBroadcaster(t)
- uni.hb = commonmocks.NewHeadBroadcaster[*evmtypes.Head, common.Hash](t)
+ uni.hb = htmocks.NewHeadBroadcaster[*evmtypes.Head, common.Hash](t)
uni.ec = evmclimocks.NewClient(t)
db := pgtest.NewSqlxDB(t)
@@ -112,7 +113,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
rawLog := cltest.LogFromFixture(t, "../../../testdata/jsonrpc/ocr2_round_requested_log_1_1.json")
logBroadcast.On("RawLog").Return(rawLog).Maybe()
logBroadcast.On("String").Return("").Maybe()
- uni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
configDigest, epoch, round, err := uni.requestRoundTracker.LatestRoundRequested(testutils.Context(t), 0)
@@ -121,7 +122,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
require.Equal(t, 0, int(round))
require.Equal(t, 0, int(epoch))
- uni.requestRoundTracker.HandleLog(logBroadcast)
+ uni.requestRoundTracker.HandleLog(tests.Context(t), logBroadcast)
configDigest, epoch, round, err = uni.requestRoundTracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -143,7 +144,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
require.Equal(t, 0, int(round))
require.Equal(t, 0, int(epoch))
- uni.requestRoundTracker.HandleLog(logBroadcast)
+ uni.requestRoundTracker.HandleLog(tests.Context(t), logBroadcast)
configDigest, epoch, round, err = uni.requestRoundTracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -168,19 +169,14 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
logBroadcast.On("RawLog").Return(rawLog).Maybe()
logBroadcast.On("String").Return("").Maybe()
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- uni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr ocr2aggregator.OCR2AggregatorRoundRequested) bool {
return rr.Epoch == 1 && rr.Round == 1
})).Return(nil)
- transact := uni.db.On("Transact", mock.Anything, mock.Anything)
- transact.Run(func(args mock.Arguments) {
- fn := args[1].(func(evm.RequestRoundDB) error)
- err2 := fn(uni.db)
- transact.ReturnArguments = []any{err2}
- })
+ uni.db.On("WithDataSource", mock.Anything).Return(uni.db)
- uni.requestRoundTracker.HandleLog(logBroadcast)
+ uni.requestRoundTracker.HandleLog(tests.Context(t), logBroadcast)
configDigest, epoch, round, err = uni.requestRoundTracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -194,13 +190,13 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
logBroadcast2.On("RawLog").Return(rawLog2).Maybe()
logBroadcast2.On("String").Return("").Maybe()
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- uni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr ocr2aggregator.OCR2AggregatorRoundRequested) bool {
return rr.Epoch == 1 && rr.Round == 9
})).Return(nil)
- uni.requestRoundTracker.HandleLog(logBroadcast2)
+ uni.requestRoundTracker.HandleLog(tests.Context(t), logBroadcast2)
configDigest, epoch, round, err = uni.requestRoundTracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -209,7 +205,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
assert.Equal(t, 9, int(round))
// Same round with lower epoch is ignored
- uni.requestRoundTracker.HandleLog(logBroadcast)
+ uni.requestRoundTracker.HandleLog(tests.Context(t), logBroadcast)
configDigest, epoch, round, err = uni.requestRoundTracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -224,13 +220,13 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
logBroadcast3.On("RawLog").Return(rawLog3).Maybe()
logBroadcast3.On("String").Return("").Maybe()
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- uni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil)
+ uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil)
uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr ocr2aggregator.OCR2AggregatorRoundRequested) bool {
return rr.Epoch == 2 && rr.Round == 1
})).Return(nil)
- uni.requestRoundTracker.HandleLog(logBroadcast3)
+ uni.requestRoundTracker.HandleLog(tests.Context(t), logBroadcast3)
configDigest, epoch, round, err = uni.requestRoundTracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
@@ -250,14 +246,9 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin
uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything).Return(errors.New("something exploded"))
- transact := uni.db.On("Transact", mock.Anything, mock.Anything)
- transact.Run(func(args mock.Arguments) {
- fn := args[1].(func(evm.RequestRoundDB) error)
- err := fn(uni.db)
- transact.ReturnArguments = []any{err}
- })
+ uni.db.On("WithDataSource", mock.Anything).Return(uni.db)
- uni.requestRoundTracker.HandleLog(logBroadcast)
+ uni.requestRoundTracker.HandleLog(tests.Context(t), logBroadcast)
configDigest, epoch, round, err := uni.requestRoundTracker.LatestRoundRequested(testutils.Context(t), 0)
require.NoError(t, err)
diff --git a/core/services/s4/cached_orm_wrapper.go b/core/services/s4/cached_orm_wrapper.go
index 38b9ecba1ca..fe6cb20e3cd 100644
--- a/core/services/s4/cached_orm_wrapper.go
+++ b/core/services/s4/cached_orm_wrapper.go
@@ -1,6 +1,7 @@
package s4
import (
+ "context"
"fmt"
"math/big"
"strings"
@@ -10,7 +11,6 @@ import (
ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
const (
@@ -40,18 +40,18 @@ func NewCachedORMWrapper(orm ORM, lggr logger.Logger) *CachedORM {
}
}
-func (c CachedORM) Get(address *ubig.Big, slotId uint, qopts ...pg.QOpt) (*Row, error) {
- return c.underlayingORM.Get(address, slotId, qopts...)
+func (c CachedORM) Get(ctx context.Context, address *ubig.Big, slotId uint) (*Row, error) {
+ return c.underlayingORM.Get(ctx, address, slotId)
}
-func (c CachedORM) Update(row *Row, qopts ...pg.QOpt) error {
+func (c CachedORM) Update(ctx context.Context, row *Row) error {
c.deleteRowFromSnapshotCache(row)
- return c.underlayingORM.Update(row, qopts...)
+ return c.underlayingORM.Update(ctx, row)
}
-func (c CachedORM) DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt) (int64, error) {
- deletedRows, err := c.underlayingORM.DeleteExpired(limit, utcNow, qopts...)
+func (c CachedORM) DeleteExpired(ctx context.Context, limit uint, utcNow time.Time) (int64, error) {
+ deletedRows, err := c.underlayingORM.DeleteExpired(ctx, limit, utcNow)
if err != nil {
return 0, err
}
@@ -63,7 +63,7 @@ func (c CachedORM) DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt)
return deletedRows, nil
}
-func (c CachedORM) GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt) ([]*SnapshotRow, error) {
+func (c CachedORM) GetSnapshot(ctx context.Context, addressRange *AddressRange) ([]*SnapshotRow, error) {
key := fmt.Sprintf("%s_%s_%s", getSnapshotCachePrefix, addressRange.MinAddress.String(), addressRange.MaxAddress.String())
cached, found := c.cache.Get(key)
@@ -72,7 +72,7 @@ func (c CachedORM) GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt) ([]
}
c.lggr.Debug("Snapshot not found in cache, fetching it from underlaying implementation")
- data, err := c.underlayingORM.GetSnapshot(addressRange, qopts...)
+ data, err := c.underlayingORM.GetSnapshot(ctx, addressRange)
if err != nil {
return nil, err
}
@@ -81,8 +81,8 @@ func (c CachedORM) GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt) ([]
return data, nil
}
-func (c CachedORM) GetUnconfirmedRows(limit uint, qopts ...pg.QOpt) ([]*Row, error) {
- return c.underlayingORM.GetUnconfirmedRows(limit, qopts...)
+func (c CachedORM) GetUnconfirmedRows(ctx context.Context, limit uint) ([]*Row, error) {
+ return c.underlayingORM.GetUnconfirmedRows(ctx, limit)
}
// deleteRowFromSnapshotCache will clean the cache for every snapshot that would involve a given row
diff --git a/core/services/s4/cached_orm_wrapper_test.go b/core/services/s4/cached_orm_wrapper_test.go
index 6f6ac298557..5b94ce3b253 100644
--- a/core/services/s4/cached_orm_wrapper_test.go
+++ b/core/services/s4/cached_orm_wrapper_test.go
@@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
@@ -21,11 +22,12 @@ import (
func TestGetSnapshotEmpty(t *testing.T) {
t.Run("OK-no_rows", func(t *testing.T) {
+ ctx := testutils.Context(t)
psqlORM := setupORM(t, "test")
lggr := logger.TestLogger(t)
orm := s4.NewCachedORMWrapper(psqlORM, lggr)
- rows, err := orm.GetSnapshot(s4.NewFullAddressRange())
+ rows, err := orm.GetSnapshot(ctx, s4.NewFullAddressRange())
assert.NoError(t, err)
assert.Empty(t, rows)
})
@@ -33,23 +35,24 @@ func TestGetSnapshotEmpty(t *testing.T) {
func TestGetSnapshotCacheFilled(t *testing.T) {
t.Run("OK_with_rows_already_cached", func(t *testing.T) {
+ ctx := testutils.Context(t)
rows := generateTestSnapshotRows(t, 100)
fullAddressRange := s4.NewFullAddressRange()
lggr := logger.TestLogger(t)
underlayingORM := mocks.NewORM(t)
- underlayingORM.On("GetSnapshot", fullAddressRange).Return(rows, nil).Once()
+ underlayingORM.On("GetSnapshot", mock.Anything, fullAddressRange).Return(rows, nil).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
// first call will go to the underlaying orm implementation to fill the cache
- first_snapshot, err := orm.GetSnapshot(fullAddressRange)
+ first_snapshot, err := orm.GetSnapshot(ctx, fullAddressRange)
assert.NoError(t, err)
assert.Equal(t, len(rows), len(first_snapshot))
// on the second call, the results will come from the cache, if not the mock will return an error because of .Once()
- cache_snapshot, err := orm.GetSnapshot(fullAddressRange)
+ cache_snapshot, err := orm.GetSnapshot(ctx, fullAddressRange)
assert.NoError(t, err)
assert.Equal(t, len(rows), len(cache_snapshot))
@@ -75,23 +78,24 @@ func TestGetSnapshotCacheFilled(t *testing.T) {
func TestUpdateInvalidatesSnapshotCache(t *testing.T) {
t.Run("OK-GetSnapshot_cache_invalidated_after_update", func(t *testing.T) {
+ ctx := testutils.Context(t)
rows := generateTestSnapshotRows(t, 100)
fullAddressRange := s4.NewFullAddressRange()
lggr := logger.TestLogger(t)
underlayingORM := mocks.NewORM(t)
- underlayingORM.On("GetSnapshot", fullAddressRange).Return(rows, nil).Once()
+ underlayingORM.On("GetSnapshot", mock.Anything, fullAddressRange).Return(rows, nil).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
// first call will go to the underlaying orm implementation to fill the cache
- first_snapshot, err := orm.GetSnapshot(fullAddressRange)
+ first_snapshot, err := orm.GetSnapshot(ctx, fullAddressRange)
assert.NoError(t, err)
assert.Equal(t, len(rows), len(first_snapshot))
// on the second call, the results will come from the cache, if not the mock will return an error because of .Once()
- cache_snapshot, err := orm.GetSnapshot(fullAddressRange)
+ cache_snapshot, err := orm.GetSnapshot(ctx, fullAddressRange)
assert.NoError(t, err)
assert.Equal(t, len(rows), len(cache_snapshot))
@@ -105,18 +109,19 @@ func TestUpdateInvalidatesSnapshotCache(t *testing.T) {
Confirmed: true,
Signature: cltest.MustRandomBytes(t, 32),
}
- underlayingORM.On("Update", row).Return(nil).Once()
- err = orm.Update(row)
+ underlayingORM.On("Update", mock.Anything, row).Return(nil).Once()
+ err = orm.Update(ctx, row)
assert.NoError(t, err)
// given the cache was invalidated this request will reach the underlaying orm implementation
- underlayingORM.On("GetSnapshot", fullAddressRange).Return(rows, nil).Once()
- third_snapshot, err := orm.GetSnapshot(fullAddressRange)
+ underlayingORM.On("GetSnapshot", mock.Anything, fullAddressRange).Return(rows, nil).Once()
+ third_snapshot, err := orm.GetSnapshot(ctx, fullAddressRange)
assert.NoError(t, err)
assert.Equal(t, len(rows), len(third_snapshot))
})
t.Run("OK-GetSnapshot_cache_not_invalidated_after_update", func(t *testing.T) {
+ ctx := testutils.Context(t)
rows := generateTestSnapshotRows(t, 5)
addressRange := &s4.AddressRange{
@@ -126,17 +131,17 @@ func TestUpdateInvalidatesSnapshotCache(t *testing.T) {
lggr := logger.TestLogger(t)
underlayingORM := mocks.NewORM(t)
- underlayingORM.On("GetSnapshot", addressRange).Return(rows, nil).Once()
+ underlayingORM.On("GetSnapshot", mock.Anything, addressRange).Return(rows, nil).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
// first call will go to the underlaying orm implementation to fill the cache
- first_snapshot, err := orm.GetSnapshot(addressRange)
+ first_snapshot, err := orm.GetSnapshot(ctx, addressRange)
assert.NoError(t, err)
assert.Equal(t, len(rows), len(first_snapshot))
// on the second call, the results will come from the cache, if not the mock will return an error because of .Once()
- cache_snapshot, err := orm.GetSnapshot(addressRange)
+ cache_snapshot, err := orm.GetSnapshot(ctx, addressRange)
assert.NoError(t, err)
assert.Equal(t, len(rows), len(cache_snapshot))
@@ -151,12 +156,12 @@ func TestUpdateInvalidatesSnapshotCache(t *testing.T) {
Confirmed: true,
Signature: cltest.MustRandomBytes(t, 32),
}
- underlayingORM.On("Update", row).Return(nil).Once()
- err = orm.Update(row)
+ underlayingORM.On("Update", mock.Anything, row).Return(nil).Once()
+ err = orm.Update(ctx, row)
assert.NoError(t, err)
// given the cache was not invalidated this request wont reach the underlaying orm implementation
- third_snapshot, err := orm.GetSnapshot(addressRange)
+ third_snapshot, err := orm.GetSnapshot(ctx, addressRange)
assert.NoError(t, err)
assert.Equal(t, len(rows), len(third_snapshot))
})
@@ -169,24 +174,26 @@ func TestGet(t *testing.T) {
lggr := logger.TestLogger(t)
t.Run("OK-Get_underlaying_ORM_returns_a_row", func(t *testing.T) {
+ ctx := testutils.Context(t)
underlayingORM := mocks.NewORM(t)
expectedRow := &s4.Row{
Address: address,
SlotId: slotID,
}
- underlayingORM.On("Get", address, slotID).Return(expectedRow, nil).Once()
+ underlayingORM.On("Get", mock.Anything, address, slotID).Return(expectedRow, nil).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
- row, err := orm.Get(address, slotID)
+ row, err := orm.Get(ctx, address, slotID)
require.NoError(t, err)
require.Equal(t, expectedRow, row)
})
t.Run("NOK-Get_underlaying_ORM_returns_an_error", func(t *testing.T) {
+ ctx := testutils.Context(t)
underlayingORM := mocks.NewORM(t)
- underlayingORM.On("Get", address, slotID).Return(nil, fmt.Errorf("some_error")).Once()
+ underlayingORM.On("Get", mock.Anything, address, slotID).Return(nil, fmt.Errorf("some_error")).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
- row, err := orm.Get(address, slotID)
+ row, err := orm.Get(ctx, address, slotID)
require.Nil(t, row)
require.EqualError(t, err, "some_error")
})
@@ -199,22 +206,24 @@ func TestDeletedExpired(t *testing.T) {
lggr := logger.TestLogger(t)
t.Run("OK-DeletedExpired_underlaying_ORM_returns_a_row", func(t *testing.T) {
+ ctx := testutils.Context(t)
var expectedDeleted int64 = 10
underlayingORM := mocks.NewORM(t)
- underlayingORM.On("DeleteExpired", limit, now).Return(expectedDeleted, nil).Once()
+ underlayingORM.On("DeleteExpired", mock.Anything, limit, now).Return(expectedDeleted, nil).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
- actualDeleted, err := orm.DeleteExpired(limit, now)
+ actualDeleted, err := orm.DeleteExpired(ctx, limit, now)
require.NoError(t, err)
require.Equal(t, expectedDeleted, actualDeleted)
})
t.Run("NOK-DeletedExpired_underlaying_ORM_returns_an_error", func(t *testing.T) {
+ ctx := testutils.Context(t)
var expectedDeleted int64
underlayingORM := mocks.NewORM(t)
- underlayingORM.On("DeleteExpired", limit, now).Return(expectedDeleted, fmt.Errorf("some_error")).Once()
+ underlayingORM.On("DeleteExpired", mock.Anything, limit, now).Return(expectedDeleted, fmt.Errorf("some_error")).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
- actualDeleted, err := orm.DeleteExpired(limit, now)
+ actualDeleted, err := orm.DeleteExpired(ctx, limit, now)
require.EqualError(t, err, "some_error")
require.Equal(t, expectedDeleted, actualDeleted)
})
@@ -226,6 +235,7 @@ func TestGetUnconfirmedRows(t *testing.T) {
lggr := logger.TestLogger(t)
t.Run("OK-GetUnconfirmedRows_underlaying_ORM_returns_a_row", func(t *testing.T) {
+ ctx := testutils.Context(t)
address := big.New(testutils.NewAddress().Big())
var slotID uint = 1
@@ -234,19 +244,20 @@ func TestGetUnconfirmedRows(t *testing.T) {
SlotId: slotID,
}}
underlayingORM := mocks.NewORM(t)
- underlayingORM.On("GetUnconfirmedRows", limit).Return(expectedRow, nil).Once()
+ underlayingORM.On("GetUnconfirmedRows", mock.Anything, limit).Return(expectedRow, nil).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
- actualRow, err := orm.GetUnconfirmedRows(limit)
+ actualRow, err := orm.GetUnconfirmedRows(ctx, limit)
require.NoError(t, err)
require.Equal(t, expectedRow, actualRow)
})
t.Run("NOK-GetUnconfirmedRows_underlaying_ORM_returns_an_error", func(t *testing.T) {
+ ctx := testutils.Context(t)
underlayingORM := mocks.NewORM(t)
- underlayingORM.On("GetUnconfirmedRows", limit).Return(nil, fmt.Errorf("some_error")).Once()
+ underlayingORM.On("GetUnconfirmedRows", mock.Anything, limit).Return(nil, fmt.Errorf("some_error")).Once()
orm := s4.NewCachedORMWrapper(underlayingORM, lggr)
- actualRow, err := orm.GetUnconfirmedRows(limit)
+ actualRow, err := orm.GetUnconfirmedRows(ctx, limit)
require.Nil(t, actualRow)
require.EqualError(t, err, "some_error")
})
diff --git a/core/services/s4/in_memory_orm.go b/core/services/s4/in_memory_orm.go
index 28b50ce430c..723f8820999 100644
--- a/core/services/s4/in_memory_orm.go
+++ b/core/services/s4/in_memory_orm.go
@@ -1,12 +1,12 @@
package s4
import (
+ "context"
"sort"
"sync"
"time"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
type key struct {
@@ -32,7 +32,7 @@ func NewInMemoryORM() ORM {
}
}
-func (o *inMemoryOrm) Get(address *big.Big, slotId uint, qopts ...pg.QOpt) (*Row, error) {
+func (o *inMemoryOrm) Get(ctx context.Context, address *big.Big, slotId uint) (*Row, error) {
o.mu.RLock()
defer o.mu.RUnlock()
@@ -47,7 +47,7 @@ func (o *inMemoryOrm) Get(address *big.Big, slotId uint, qopts ...pg.QOpt) (*Row
return mrow.Row.Clone(), nil
}
-func (o *inMemoryOrm) Update(row *Row, qopts ...pg.QOpt) error {
+func (o *inMemoryOrm) Update(ctx context.Context, row *Row) error {
o.mu.Lock()
defer o.mu.Unlock()
@@ -74,7 +74,7 @@ func (o *inMemoryOrm) Update(row *Row, qopts ...pg.QOpt) error {
return nil
}
-func (o *inMemoryOrm) DeleteExpired(limit uint, now time.Time, qopts ...pg.QOpt) (int64, error) {
+func (o *inMemoryOrm) DeleteExpired(ctx context.Context, limit uint, now time.Time) (int64, error) {
o.mu.Lock()
defer o.mu.Unlock()
@@ -94,7 +94,7 @@ func (o *inMemoryOrm) DeleteExpired(limit uint, now time.Time, qopts ...pg.QOpt)
return int64(len(queue)), nil
}
-func (o *inMemoryOrm) GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt) ([]*SnapshotRow, error) {
+func (o *inMemoryOrm) GetSnapshot(ctx context.Context, _ *AddressRange) ([]*SnapshotRow, error) {
o.mu.RLock()
defer o.mu.RUnlock()
@@ -115,7 +115,7 @@ func (o *inMemoryOrm) GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt)
return rows, nil
}
-func (o *inMemoryOrm) GetUnconfirmedRows(limit uint, qopts ...pg.QOpt) ([]*Row, error) {
+func (o *inMemoryOrm) GetUnconfirmedRows(ctx context.Context, limit uint) ([]*Row, error) {
o.mu.RLock()
defer o.mu.RUnlock()
diff --git a/core/services/s4/in_memory_orm_test.go b/core/services/s4/in_memory_orm_test.go
index 318db5f1a44..db4f73ba1ef 100644
--- a/core/services/s4/in_memory_orm_test.go
+++ b/core/services/s4/in_memory_orm_test.go
@@ -33,33 +33,36 @@ func TestInMemoryORM(t *testing.T) {
orm := s4.NewInMemoryORM()
t.Run("row not found", func(t *testing.T) {
- _, err := orm.Get(big.New(address.Big()), slotId)
+ ctx := testutils.Context(t)
+ _, err := orm.Get(ctx, big.New(address.Big()), slotId)
assert.ErrorIs(t, err, s4.ErrNotFound)
})
t.Run("insert and get", func(t *testing.T) {
- err := orm.Update(row)
+ ctx := testutils.Context(t)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
- e, err := orm.Get(big.New(address.Big()), slotId)
+ e, err := orm.Get(ctx, big.New(address.Big()), slotId)
assert.NoError(t, err)
assert.Equal(t, row, e)
})
t.Run("update and get", func(t *testing.T) {
+ ctx := testutils.Context(t)
row.Version = 5
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
// unconfirmed row requires greater version
- err = orm.Update(row)
+ err = orm.Update(ctx, row)
assert.ErrorIs(t, err, s4.ErrVersionTooLow)
row.Confirmed = true
- err = orm.Update(row)
+ err = orm.Update(ctx, row)
assert.NoError(t, err)
- e, err := orm.Get(big.New(address.Big()), slotId)
+ e, err := orm.Get(ctx, big.New(address.Big()), slotId)
assert.NoError(t, err)
assert.Equal(t, row, e)
})
@@ -67,6 +70,7 @@ func TestInMemoryORM(t *testing.T) {
func TestInMemoryORM_DeleteExpired(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := s4.NewInMemoryORM()
baseTime := time.Now().Add(time.Minute).UTC()
@@ -84,22 +88,23 @@ func TestInMemoryORM_DeleteExpired(t *testing.T) {
Confirmed: false,
Signature: []byte{},
}
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
}
deadline := baseTime.Add(100 * time.Second)
- count, err := orm.DeleteExpired(200, deadline)
+ count, err := orm.DeleteExpired(ctx, 200, deadline)
assert.NoError(t, err)
assert.Equal(t, int64(100), count)
- rows, err := orm.GetUnconfirmedRows(200)
+ rows, err := orm.GetUnconfirmedRows(ctx, 200)
assert.NoError(t, err)
assert.Len(t, rows, 156)
}
func TestInMemoryORM_GetUnconfirmedRows(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := s4.NewInMemoryORM()
expiration := time.Now().Add(100 * time.Second).UnixMilli()
@@ -117,18 +122,19 @@ func TestInMemoryORM_GetUnconfirmedRows(t *testing.T) {
Confirmed: i >= 100,
Signature: []byte{},
}
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
time.Sleep(time.Millisecond)
}
- rows, err := orm.GetUnconfirmedRows(100)
+ rows, err := orm.GetUnconfirmedRows(ctx, 100)
assert.NoError(t, err)
assert.Len(t, rows, 100)
}
func TestInMemoryORM_GetSnapshot(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := s4.NewInMemoryORM()
expiration := time.Now().Add(100 * time.Second).UnixMilli()
@@ -147,11 +153,11 @@ func TestInMemoryORM_GetSnapshot(t *testing.T) {
Confirmed: i >= 100,
Signature: []byte{},
}
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
}
- rows, err := orm.GetSnapshot(s4.NewFullAddressRange())
+ rows, err := orm.GetSnapshot(ctx, s4.NewFullAddressRange())
assert.NoError(t, err)
assert.Len(t, rows, n)
diff --git a/core/services/s4/mocks/orm.go b/core/services/s4/mocks/orm.go
index 3b8cac8e76d..4a5d7fa992d 100644
--- a/core/services/s4/mocks/orm.go
+++ b/core/services/s4/mocks/orm.go
@@ -3,10 +3,11 @@
package mocks
import (
+ context "context"
+
big "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
- mock "github.com/stretchr/testify/mock"
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ mock "github.com/stretchr/testify/mock"
s4 "github.com/smartcontractkit/chainlink/v2/core/services/s4"
@@ -18,16 +19,9 @@ type ORM struct {
mock.Mock
}
-// DeleteExpired provides a mock function with given fields: limit, utcNow, qopts
-func (_m *ORM) DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt) (int64, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, limit, utcNow)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// DeleteExpired provides a mock function with given fields: ctx, limit, utcNow
+func (_m *ORM) DeleteExpired(ctx context.Context, limit uint, utcNow time.Time) (int64, error) {
+ ret := _m.Called(ctx, limit, utcNow)
if len(ret) == 0 {
panic("no return value specified for DeleteExpired")
@@ -35,17 +29,17 @@ func (_m *ORM) DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt) (in
var r0 int64
var r1 error
- if rf, ok := ret.Get(0).(func(uint, time.Time, ...pg.QOpt) (int64, error)); ok {
- return rf(limit, utcNow, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint, time.Time) (int64, error)); ok {
+ return rf(ctx, limit, utcNow)
}
- if rf, ok := ret.Get(0).(func(uint, time.Time, ...pg.QOpt) int64); ok {
- r0 = rf(limit, utcNow, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint, time.Time) int64); ok {
+ r0 = rf(ctx, limit, utcNow)
} else {
r0 = ret.Get(0).(int64)
}
- if rf, ok := ret.Get(1).(func(uint, time.Time, ...pg.QOpt) error); ok {
- r1 = rf(limit, utcNow, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, uint, time.Time) error); ok {
+ r1 = rf(ctx, limit, utcNow)
} else {
r1 = ret.Error(1)
}
@@ -53,16 +47,9 @@ func (_m *ORM) DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt) (in
return r0, r1
}
-// Get provides a mock function with given fields: address, slotId, qopts
-func (_m *ORM) Get(address *big.Big, slotId uint, qopts ...pg.QOpt) (*s4.Row, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, address, slotId)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// Get provides a mock function with given fields: ctx, address, slotId
+func (_m *ORM) Get(ctx context.Context, address *big.Big, slotId uint) (*s4.Row, error) {
+ ret := _m.Called(ctx, address, slotId)
if len(ret) == 0 {
panic("no return value specified for Get")
@@ -70,19 +57,19 @@ func (_m *ORM) Get(address *big.Big, slotId uint, qopts ...pg.QOpt) (*s4.Row, er
var r0 *s4.Row
var r1 error
- if rf, ok := ret.Get(0).(func(*big.Big, uint, ...pg.QOpt) (*s4.Row, error)); ok {
- return rf(address, slotId, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *big.Big, uint) (*s4.Row, error)); ok {
+ return rf(ctx, address, slotId)
}
- if rf, ok := ret.Get(0).(func(*big.Big, uint, ...pg.QOpt) *s4.Row); ok {
- r0 = rf(address, slotId, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *big.Big, uint) *s4.Row); ok {
+ r0 = rf(ctx, address, slotId)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*s4.Row)
}
}
- if rf, ok := ret.Get(1).(func(*big.Big, uint, ...pg.QOpt) error); ok {
- r1 = rf(address, slotId, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, *big.Big, uint) error); ok {
+ r1 = rf(ctx, address, slotId)
} else {
r1 = ret.Error(1)
}
@@ -90,16 +77,9 @@ func (_m *ORM) Get(address *big.Big, slotId uint, qopts ...pg.QOpt) (*s4.Row, er
return r0, r1
}
-// GetSnapshot provides a mock function with given fields: addressRange, qopts
-func (_m *ORM) GetSnapshot(addressRange *s4.AddressRange, qopts ...pg.QOpt) ([]*s4.SnapshotRow, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, addressRange)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// GetSnapshot provides a mock function with given fields: ctx, addressRange
+func (_m *ORM) GetSnapshot(ctx context.Context, addressRange *s4.AddressRange) ([]*s4.SnapshotRow, error) {
+ ret := _m.Called(ctx, addressRange)
if len(ret) == 0 {
panic("no return value specified for GetSnapshot")
@@ -107,19 +87,19 @@ func (_m *ORM) GetSnapshot(addressRange *s4.AddressRange, qopts ...pg.QOpt) ([]*
var r0 []*s4.SnapshotRow
var r1 error
- if rf, ok := ret.Get(0).(func(*s4.AddressRange, ...pg.QOpt) ([]*s4.SnapshotRow, error)); ok {
- return rf(addressRange, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *s4.AddressRange) ([]*s4.SnapshotRow, error)); ok {
+ return rf(ctx, addressRange)
}
- if rf, ok := ret.Get(0).(func(*s4.AddressRange, ...pg.QOpt) []*s4.SnapshotRow); ok {
- r0 = rf(addressRange, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *s4.AddressRange) []*s4.SnapshotRow); ok {
+ r0 = rf(ctx, addressRange)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*s4.SnapshotRow)
}
}
- if rf, ok := ret.Get(1).(func(*s4.AddressRange, ...pg.QOpt) error); ok {
- r1 = rf(addressRange, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, *s4.AddressRange) error); ok {
+ r1 = rf(ctx, addressRange)
} else {
r1 = ret.Error(1)
}
@@ -127,16 +107,9 @@ func (_m *ORM) GetSnapshot(addressRange *s4.AddressRange, qopts ...pg.QOpt) ([]*
return r0, r1
}
-// GetUnconfirmedRows provides a mock function with given fields: limit, qopts
-func (_m *ORM) GetUnconfirmedRows(limit uint, qopts ...pg.QOpt) ([]*s4.Row, error) {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, limit)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// GetUnconfirmedRows provides a mock function with given fields: ctx, limit
+func (_m *ORM) GetUnconfirmedRows(ctx context.Context, limit uint) ([]*s4.Row, error) {
+ ret := _m.Called(ctx, limit)
if len(ret) == 0 {
panic("no return value specified for GetUnconfirmedRows")
@@ -144,19 +117,19 @@ func (_m *ORM) GetUnconfirmedRows(limit uint, qopts ...pg.QOpt) ([]*s4.Row, erro
var r0 []*s4.Row
var r1 error
- if rf, ok := ret.Get(0).(func(uint, ...pg.QOpt) ([]*s4.Row, error)); ok {
- return rf(limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint) ([]*s4.Row, error)); ok {
+ return rf(ctx, limit)
}
- if rf, ok := ret.Get(0).(func(uint, ...pg.QOpt) []*s4.Row); ok {
- r0 = rf(limit, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, uint) []*s4.Row); ok {
+ r0 = rf(ctx, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*s4.Row)
}
}
- if rf, ok := ret.Get(1).(func(uint, ...pg.QOpt) error); ok {
- r1 = rf(limit, qopts...)
+ if rf, ok := ret.Get(1).(func(context.Context, uint) error); ok {
+ r1 = rf(ctx, limit)
} else {
r1 = ret.Error(1)
}
@@ -164,24 +137,17 @@ func (_m *ORM) GetUnconfirmedRows(limit uint, qopts ...pg.QOpt) ([]*s4.Row, erro
return r0, r1
}
-// Update provides a mock function with given fields: row, qopts
-func (_m *ORM) Update(row *s4.Row, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, row)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// Update provides a mock function with given fields: ctx, row
+func (_m *ORM) Update(ctx context.Context, row *s4.Row) error {
+ ret := _m.Called(ctx, row)
if len(ret) == 0 {
panic("no return value specified for Update")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*s4.Row, ...pg.QOpt) error); ok {
- r0 = rf(row, qopts...)
+ if rf, ok := ret.Get(0).(func(context.Context, *s4.Row) error); ok {
+ r0 = rf(ctx, row)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/s4/orm.go b/core/services/s4/orm.go
index 4d3cee9312a..952d8a33b24 100644
--- a/core/services/s4/orm.go
+++ b/core/services/s4/orm.go
@@ -1,10 +1,10 @@
package s4
import (
+ "context"
"time"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
// Row represents a data row persisted by ORM.
@@ -36,26 +36,26 @@ type ORM interface {
// Get reads a row for the given address and slotId combination.
// If such row does not exist, ErrNotFound is returned.
// There is no filter on Expiration.
- Get(address *big.Big, slotId uint, qopts ...pg.QOpt) (*Row, error)
+ Get(ctx context.Context, address *big.Big, slotId uint) (*Row, error)
// Update inserts or updates the row identified by (Address, SlotId) pair.
// When updating, the new row must have greater or equal version,
// otherwise ErrVersionTooLow is returned.
// UpdatedAt field value is ignored.
- Update(row *Row, qopts ...pg.QOpt) error
+ Update(ctx context.Context, row *Row) error
// DeleteExpired deletes any entries having Expiration < utcNow,
// up to the given limit.
// Returns the number of deleted rows.
- DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt) (int64, error)
+ DeleteExpired(ctx context.Context, limit uint, utcNow time.Time) (int64, error)
// GetSnapshot selects all non-expired row versions for the given addresses range.
// For the full address range, use NewFullAddressRange().
- GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt) ([]*SnapshotRow, error)
+ GetSnapshot(ctx context.Context, addressRange *AddressRange) ([]*SnapshotRow, error)
// GetUnconfirmedRows selects all non-expired, non-confirmed rows ordered by UpdatedAt.
// The number of returned rows is limited to the given limit.
- GetUnconfirmedRows(limit uint, qopts ...pg.QOpt) ([]*Row, error)
+ GetUnconfirmedRows(ctx context.Context, limit uint) ([]*Row, error)
}
func (r Row) Clone() *Row {
diff --git a/core/services/s4/postgres_orm.go b/core/services/s4/postgres_orm.go
index 1f92f2e1281..3d271e543d7 100644
--- a/core/services/s4/postgres_orm.go
+++ b/core/services/s4/postgres_orm.go
@@ -1,16 +1,15 @@
package s4
import (
+ "context"
"database/sql"
"fmt"
"time"
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
-
- "github.com/jmoiron/sqlx"
"github.com/pkg/errors"
+
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
)
const (
@@ -19,28 +18,27 @@ const (
)
type orm struct {
- q pg.Q
+ ds sqlutil.DataSource
tableName string
namespace string
}
var _ ORM = (*orm)(nil)
-func NewPostgresORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, tableName, namespace string) ORM {
+func NewPostgresORM(ds sqlutil.DataSource, tableName, namespace string) ORM {
return &orm{
- q: pg.NewQ(db, lggr, cfg),
+ ds: ds,
tableName: fmt.Sprintf(`"%s".%s`, s4PostgresSchema, tableName),
namespace: namespace,
}
}
-func (o orm) Get(address *big.Big, slotId uint, qopts ...pg.QOpt) (*Row, error) {
+func (o *orm) Get(ctx context.Context, address *big.Big, slotId uint) (*Row, error) {
row := &Row{}
- q := o.q.WithOpts(qopts...)
stmt := fmt.Sprintf(`SELECT address, slot_id, version, expiration, confirmed, payload, signature FROM %s
WHERE namespace=$1 AND address=$2 AND slot_id=$3;`, o.tableName)
- if err := q.Get(row, stmt, o.namespace, address, slotId); err != nil {
+ if err := o.ds.GetContext(ctx, row, stmt, o.namespace, address, slotId); err != nil {
if errors.Is(err, sql.ErrNoRows) {
err = ErrNotFound
}
@@ -49,9 +47,7 @@ WHERE namespace=$1 AND address=$2 AND slot_id=$3;`, o.tableName)
return row, nil
}
-func (o orm) Update(row *Row, qopts ...pg.QOpt) error {
- q := o.q.WithOpts(qopts...)
-
+func (o *orm) Update(ctx context.Context, row *Row) error {
// This query inserts or updates a row, depending on whether the version is higher than the existing one.
// We only allow the same version when the row is confirmed.
// We never transition back from unconfirmed to confirmed state.
@@ -67,31 +63,28 @@ updated_at = NOW()
WHERE (t.version < EXCLUDED.version) OR (t.version <= EXCLUDED.version AND EXCLUDED.confirmed IS TRUE)
RETURNING id;`, o.tableName)
var id uint64
- err := q.Get(&id, stmt, o.namespace, row.Address, row.SlotId, row.Version, row.Expiration, row.Confirmed, row.Payload, row.Signature)
+ err := o.ds.GetContext(ctx, &id, stmt, o.namespace, row.Address, row.SlotId, row.Version, row.Expiration, row.Confirmed, row.Payload, row.Signature)
if errors.Is(err, sql.ErrNoRows) {
return ErrVersionTooLow
}
return err
}
-func (o orm) DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt) (int64, error) {
- q := o.q.WithOpts(qopts...)
-
+func (o *orm) DeleteExpired(ctx context.Context, limit uint, utcNow time.Time) (int64, error) {
with := fmt.Sprintf(`WITH rows AS (SELECT id FROM %s WHERE namespace = $1 AND expiration < $2 LIMIT $3)`, o.tableName)
stmt := fmt.Sprintf(`%s DELETE FROM %s WHERE id IN (SELECT id FROM rows);`, with, o.tableName)
- result, err := q.Exec(stmt, o.namespace, utcNow.UnixMilli(), limit)
+ result, err := o.ds.ExecContext(ctx, stmt, o.namespace, utcNow.UnixMilli(), limit)
if err != nil {
return 0, err
}
return result.RowsAffected()
}
-func (o orm) GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt) ([]*SnapshotRow, error) {
- q := o.q.WithOpts(qopts...)
+func (o *orm) GetSnapshot(ctx context.Context, addressRange *AddressRange) ([]*SnapshotRow, error) {
rows := make([]*SnapshotRow, 0)
stmt := fmt.Sprintf(`SELECT address, slot_id, version, expiration, confirmed, octet_length(payload) AS payload_size FROM %s WHERE namespace = $1 AND address >= $2 AND address <= $3;`, o.tableName)
- if err := q.Select(&rows, stmt, o.namespace, addressRange.MinAddress, addressRange.MaxAddress); err != nil {
+ if err := o.ds.SelectContext(ctx, &rows, stmt, o.namespace, addressRange.MinAddress, addressRange.MaxAddress); err != nil {
if !errors.Is(err, sql.ErrNoRows) {
return nil, err
}
@@ -99,13 +92,12 @@ func (o orm) GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt) ([]*Snaps
return rows, nil
}
-func (o orm) GetUnconfirmedRows(limit uint, qopts ...pg.QOpt) ([]*Row, error) {
- q := o.q.WithOpts(qopts...)
+func (o *orm) GetUnconfirmedRows(ctx context.Context, limit uint) ([]*Row, error) {
rows := make([]*Row, 0)
stmt := fmt.Sprintf(`SELECT address, slot_id, version, expiration, confirmed, payload, signature FROM %s
WHERE namespace = $1 AND confirmed IS FALSE ORDER BY updated_at LIMIT $2;`, o.tableName)
- if err := q.Select(&rows, stmt, o.namespace, limit); err != nil {
+ if err := o.ds.SelectContext(ctx, &rows, stmt, o.namespace, limit); err != nil {
if !errors.Is(err, sql.ErrNoRows) {
return nil, err
}
diff --git a/core/services/s4/postgres_orm_test.go b/core/services/s4/postgres_orm_test.go
index d26f082ce5b..660002a2e3b 100644
--- a/core/services/s4/postgres_orm_test.go
+++ b/core/services/s4/postgres_orm_test.go
@@ -10,7 +10,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/s4"
"github.com/stretchr/testify/assert"
@@ -20,8 +19,7 @@ func setupORM(t *testing.T, namespace string) s4.ORM {
t.Helper()
db := pgtest.NewSqlxDB(t)
- lggr := logger.TestLogger(t)
- orm := s4.NewPostgresORM(db, lggr, pgtest.NewQConfig(true), s4.SharedTableName, namespace)
+ orm := s4.NewPostgresORM(db, s4.SharedTableName, namespace)
t.Cleanup(func() {
assert.NoError(t, db.Close())
@@ -59,64 +57,67 @@ func TestNewPostgresOrm(t *testing.T) {
func TestPostgresORM_UpdateAndGet(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t, "test")
rows := generateTestRows(t, 10)
for _, row := range rows {
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
row.Version++
- err = orm.Update(row)
+ err = orm.Update(ctx, row)
assert.NoError(t, err)
- err = orm.Update(row)
+ err = orm.Update(ctx, row)
if !row.Confirmed {
assert.ErrorIs(t, err, s4.ErrVersionTooLow)
}
}
for _, row := range rows {
- gotRow, err := orm.Get(row.Address, row.SlotId)
+ gotRow, err := orm.Get(ctx, row.Address, row.SlotId)
assert.NoError(t, err)
assert.Equal(t, row, gotRow)
}
rows = generateTestRows(t, 1)
- _, err := orm.Get(rows[0].Address, rows[0].SlotId)
+ _, err := orm.Get(ctx, rows[0].Address, rows[0].SlotId)
assert.ErrorIs(t, err, s4.ErrNotFound)
}
func TestPostgresORM_UpdateSimpleFlow(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t, "test")
row := generateTestRows(t, 1)[0]
// user sends a new version
- assert.NoError(t, orm.Update(row))
+ assert.NoError(t, orm.Update(ctx, row))
// OCR round confirms it
row.Confirmed = true
- assert.NoError(t, orm.Update(row))
+ assert.NoError(t, orm.Update(ctx, row))
// user sends a higher version (unconfirmed)
row.Version++
row.Confirmed = false
- assert.NoError(t, orm.Update(row))
+ assert.NoError(t, orm.Update(ctx, row))
// and again, before OCR has a chance to confirm
row.Version++
- assert.NoError(t, orm.Update(row))
+ assert.NoError(t, orm.Update(ctx, row))
// user tries to send a lower version
row.Version--
- assert.Error(t, orm.Update(row))
+ assert.Error(t, orm.Update(ctx, row))
}
func TestPostgresORM_DeleteExpired(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t, "test")
@@ -125,17 +126,17 @@ func TestPostgresORM_DeleteExpired(t *testing.T) {
rows := generateTestRows(t, total)
for _, row := range rows {
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
}
- deleted, err := orm.DeleteExpired(expired, time.Now().Add(2*time.Hour).UTC())
+ deleted, err := orm.DeleteExpired(ctx, expired, time.Now().Add(2*time.Hour).UTC())
assert.NoError(t, err)
assert.Equal(t, int64(expired), deleted)
count := 0
for _, row := range rows {
- _, err := orm.Get(row.Address, row.SlotId)
+ _, err := orm.Get(ctx, row.Address, row.SlotId)
if !errors.Is(err, s4.ErrNotFound) {
count++
}
@@ -149,21 +150,23 @@ func TestPostgresORM_GetSnapshot(t *testing.T) {
orm := setupORM(t, "test")
t.Run("no rows", func(t *testing.T) {
- rows, err := orm.GetSnapshot(s4.NewFullAddressRange())
+ ctx := testutils.Context(t)
+ rows, err := orm.GetSnapshot(ctx, s4.NewFullAddressRange())
assert.NoError(t, err)
assert.Empty(t, rows)
})
t.Run("with rows", func(t *testing.T) {
+ ctx := testutils.Context(t)
rows := generateTestRows(t, 100)
for _, row := range rows {
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
}
t.Run("full range", func(t *testing.T) {
- snapshot, err := orm.GetSnapshot(s4.NewFullAddressRange())
+ snapshot, err := orm.GetSnapshot(testutils.Context(t), s4.NewFullAddressRange())
assert.NoError(t, err)
assert.Equal(t, len(rows), len(snapshot))
@@ -188,7 +191,7 @@ func TestPostgresORM_GetSnapshot(t *testing.T) {
t.Run("half range", func(t *testing.T) {
ar, err := s4.NewInitialAddressRangeForIntervals(2)
assert.NoError(t, err)
- snapshot, err := orm.GetSnapshot(ar)
+ snapshot, err := orm.GetSnapshot(testutils.Context(t), ar)
assert.NoError(t, err)
for _, sr := range snapshot {
assert.True(t, ar.Contains(sr.Address))
@@ -203,21 +206,23 @@ func TestPostgresORM_GetUnconfirmedRows(t *testing.T) {
orm := setupORM(t, "test")
t.Run("no rows", func(t *testing.T) {
- rows, err := orm.GetUnconfirmedRows(5)
+ ctx := testutils.Context(t)
+ rows, err := orm.GetUnconfirmedRows(ctx, 5)
assert.NoError(t, err)
assert.Empty(t, rows)
})
t.Run("with rows", func(t *testing.T) {
+ ctx := testutils.Context(t)
rows := generateTestRows(t, 10)
for _, row := range rows {
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
time.Sleep(testutils.TestInterval / 10)
}
- gotRows, err := orm.GetUnconfirmedRows(5)
+ gotRows, err := orm.GetUnconfirmedRows(ctx, 5)
assert.NoError(t, err)
assert.Len(t, gotRows, 5)
@@ -229,6 +234,7 @@ func TestPostgresORM_GetUnconfirmedRows(t *testing.T) {
func TestPostgresORM_Namespace(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
ormA := setupORM(t, "a")
ormB := setupORM(t, "b")
@@ -237,44 +243,45 @@ func TestPostgresORM_Namespace(t *testing.T) {
rowsA := generateTestRows(t, n)
rowsB := generateTestRows(t, n)
for i := 0; i < n; i++ {
- err := ormA.Update(rowsA[i])
+ err := ormA.Update(ctx, rowsA[i])
assert.NoError(t, err)
- err = ormB.Update(rowsB[i])
+ err = ormB.Update(ctx, rowsB[i])
assert.NoError(t, err)
}
- urowsA, err := ormA.GetUnconfirmedRows(n)
+ urowsA, err := ormA.GetUnconfirmedRows(ctx, n)
assert.NoError(t, err)
assert.Len(t, urowsA, n/2)
- urowsB, err := ormB.GetUnconfirmedRows(n)
+ urowsB, err := ormB.GetUnconfirmedRows(ctx, n)
assert.NoError(t, err)
assert.Len(t, urowsB, n/2)
- _, err = ormB.DeleteExpired(n, time.Now().UTC())
+ _, err = ormB.DeleteExpired(ctx, n, time.Now().UTC())
assert.NoError(t, err)
- snapshotA, err := ormA.GetSnapshot(s4.NewFullAddressRange())
+ snapshotA, err := ormA.GetSnapshot(ctx, s4.NewFullAddressRange())
assert.NoError(t, err)
assert.Len(t, snapshotA, n)
}
func TestPostgresORM_BigIntVersion(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
orm := setupORM(t, "test")
row := generateTestRows(t, 1)[0]
row.Version = math.MaxUint64 - 10
- err := orm.Update(row)
+ err := orm.Update(ctx, row)
assert.NoError(t, err)
row.Version++
- err = orm.Update(row)
+ err = orm.Update(ctx, row)
assert.NoError(t, err)
- gotRow, err := orm.Get(row.Address, row.SlotId)
+ gotRow, err := orm.Get(ctx, row.Address, row.SlotId)
assert.NoError(t, err)
assert.Equal(t, row, gotRow)
}
diff --git a/core/services/s4/storage.go b/core/services/s4/storage.go
index 02ba9c7bd50..1af14ec269f 100644
--- a/core/services/s4/storage.go
+++ b/core/services/s4/storage.go
@@ -5,11 +5,10 @@ import (
"github.com/jonboulle/clockwork"
+ "github.com/ethereum/go-ethereum/common"
+
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
-
- "github.com/ethereum/go-ethereum/common"
)
// Constraints specifies the global storage constraints.
@@ -95,7 +94,7 @@ func (s *storage) Get(ctx context.Context, key *Key) (*Record, *Metadata, error)
}
bigAddress := big.New(key.Address.Big())
- row, err := s.orm.Get(bigAddress, key.SlotId, pg.WithParentCtx(ctx))
+ row, err := s.orm.Get(ctx, bigAddress, key.SlotId)
if err != nil {
return nil, nil, err
}
@@ -125,7 +124,7 @@ func (s *storage) List(ctx context.Context, address common.Address) ([]*Snapshot
if err != nil {
return nil, err
}
- return s.orm.GetSnapshot(sar, pg.WithParentCtx(ctx))
+ return s.orm.GetSnapshot(ctx, sar)
}
func (s *storage) Put(ctx context.Context, key *Key, record *Record, signature []byte) error {
@@ -161,5 +160,5 @@ func (s *storage) Put(ctx context.Context, key *Key, record *Record, signature [
copy(row.Payload, record.Payload)
copy(row.Signature, signature)
- return s.orm.Update(row, pg.WithParentCtx(ctx))
+ return s.orm.Update(ctx, row)
}
diff --git a/core/services/s4/storage_test.go b/core/services/s4/storage_test.go
index b643609f449..8deb23bb979 100644
--- a/core/services/s4/storage_test.go
+++ b/core/services/s4/storage_test.go
@@ -53,7 +53,7 @@ func TestStorage_Errors(t *testing.T) {
SlotId: 1,
Version: 0,
}
- ormMock.On("Get", big.New(key.Address.Big()), key.SlotId, mock.Anything).Return(nil, s4.ErrNotFound)
+ ormMock.On("Get", mock.Anything, big.New(key.Address.Big()), key.SlotId).Return(nil, s4.ErrNotFound)
_, _, err := storage.Get(testutils.Context(t), key)
assert.ErrorIs(t, err, s4.ErrNotFound)
})
@@ -181,7 +181,7 @@ func TestStorage_PutAndGet(t *testing.T) {
assert.NoError(t, err)
ormMock.On("Update", mock.Anything, mock.Anything).Return(nil)
- ormMock.On("Get", big.New(key.Address.Big()), uint(2), mock.Anything).Return(&s4.Row{
+ ormMock.On("Get", mock.Anything, big.New(key.Address.Big()), uint(2)).Return(&s4.Row{
Address: big.New(key.Address.Big()),
SlotId: key.SlotId,
Version: key.Version,
@@ -221,7 +221,7 @@ func TestStorage_List(t *testing.T) {
addressRange, err := s4.NewSingleAddressRange(big.New(address.Big()))
assert.NoError(t, err)
- ormMock.On("GetSnapshot", addressRange, mock.Anything).Return(ormRows, nil)
+ ormMock.On("GetSnapshot", mock.Anything, addressRange).Return(ormRows, nil)
rows, err := storage.List(testutils.Context(t), address)
require.NoError(t, err)
diff --git a/core/services/streams/delegate.go b/core/services/streams/delegate.go
index f9e2a64c4a3..bf492d4bd15 100644
--- a/core/services/streams/delegate.go
+++ b/core/services/streams/delegate.go
@@ -12,7 +12,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
)
@@ -38,10 +37,10 @@ func (d *Delegate) JobType() job.Type {
return job.Stream
}
-func (d *Delegate) BeforeJobCreated(jb job.Job) {}
-func (d *Delegate) AfterJobCreated(jb job.Job) {}
-func (d *Delegate) BeforeJobDeleted(jb job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, jb job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) BeforeJobCreated(jb job.Job) {}
+func (d *Delegate) AfterJobCreated(jb job.Job) {}
+func (d *Delegate) BeforeJobDeleted(jb job.Job) {}
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services []job.ServiceCtx, err error) {
if jb.StreamID == nil {
diff --git a/core/services/streams/stream_test.go b/core/services/streams/stream_test.go
index 3c0b4d0721f..3e8f58cd58b 100644
--- a/core/services/streams/stream_test.go
+++ b/core/services/streams/stream_test.go
@@ -11,9 +11,9 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
)
@@ -32,7 +32,7 @@ func (m *mockRunner) ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pi
func (m *mockRunner) InitializePipeline(spec pipeline.Spec) (p *pipeline.Pipeline, err error) {
return m.p, m.err
}
-func (m *mockRunner) InsertFinishedRun(run *pipeline.Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error {
+func (m *mockRunner) InsertFinishedRun(ctx context.Context, ds sqlutil.DataSource, run *pipeline.Run, saveSuccessfulTaskRuns bool) error {
return m.err
}
diff --git a/core/services/synchronization/telemetry_ingress_batch_client.go b/core/services/synchronization/telemetry_ingress_batch_client.go
index b8dbb5e5d37..cade98cf606 100644
--- a/core/services/synchronization/telemetry_ingress_batch_client.go
+++ b/core/services/synchronization/telemetry_ingress_batch_client.go
@@ -113,7 +113,7 @@ func (tc *telemetryIngressBatchClient) Start(ctx context.Context) error {
if ctx2.Err() != nil {
tc.lggr.Warnw("gave up connecting to telemetry endpoint", "err", err)
} else {
- tc.lggr.Criticalw("telemetry endpoint dial errored unexpectedly", "err", err)
+ tc.lggr.Criticalw("telemetry endpoint dial errored unexpectedly", "err", err, "server pubkey", tc.serverPubKeyHex)
tc.SvcErrBuffer.Append(err)
}
return
diff --git a/core/services/synchronization/telemetry_ingress_client_test.go b/core/services/synchronization/telemetry_ingress_client_test.go
index 55be107b977..e7e14eda748 100644
--- a/core/services/synchronization/telemetry_ingress_client_test.go
+++ b/core/services/synchronization/telemetry_ingress_client_test.go
@@ -18,6 +18,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
"github.com/smartcontractkit/chainlink/v2/core/services/synchronization/mocks"
telemPb "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem"
+ telem "github.com/smartcontractkit/chainlink/v2/core/services/telemetry"
)
func TestTelemetryIngressClient_Send_HappyPath(t *testing.T) {
@@ -33,7 +34,7 @@ func TestTelemetryIngressClient_Send_HappyPath(t *testing.T) {
// Wire up the telem ingress client
url := &url.URL{}
- serverPubKeyHex := "33333333333"
+ serverPubKeyHex := telem.GetDummyKeyString()
telemIngressClient := synchronization.NewTestTelemetryIngressClient(t, url, serverPubKeyHex, csaKeystore, false, telemClient)
servicetest.Run(t, telemIngressClient)
diff --git a/core/services/telemetry/manager_test.go b/core/services/telemetry/manager_test.go
index 2d3409ba569..9b83ef08234 100644
--- a/core/services/telemetry/manager_test.go
+++ b/core/services/telemetry/manager_test.go
@@ -79,21 +79,21 @@ func TestNewManager(t *testing.T) {
network: "NETWORK-1",
chainID: "NETWORK-1-CHAINID-1",
url: "http://network-1-chainID-1.test",
- pubKey: "network-1-chainID-1-pub-key",
+ pubKey: GetDummyKeyStringWithPrefix("network-1-chainID-1-pub-key"),
shouldError: false,
},
{
network: "NETWORK-1",
chainID: "NETWORK-1-CHAINID-2",
url: "http://network-1-chainID-2.test",
- pubKey: "network-1-chainID-2-pub-key",
+ pubKey: GetDummyKeyStringWithPrefix("network-1-chainID-2-pub-key"),
shouldError: false,
},
{
network: "NETWORK-2",
chainID: "NETWORK-2-CHAINID-1",
url: "http://network-2-chainID-1.test",
- pubKey: "network-2-chainID-1-pub-key",
+ pubKey: GetDummyKeyStringWithPrefix("network-2-chainID-1-pub-key"),
shouldError: false,
},
{
@@ -122,7 +122,7 @@ func TestNewManager(t *testing.T) {
network: "NETWORK-1",
chainID: "NETWORK-1-CHAINID-1",
url: "http://network-1-chainID-1.test",
- pubKey: "network-1-chainID-1-pub-key",
+ pubKey: GetDummyKeyStringWithPrefix("network-1-chainID-1-pub-key"),
shouldError: true,
expectedError: "endpoint already exists",
},
diff --git a/core/services/telemetry/test_helpers.go b/core/services/telemetry/test_helpers.go
new file mode 100644
index 00000000000..408b46666f1
--- /dev/null
+++ b/core/services/telemetry/test_helpers.go
@@ -0,0 +1,20 @@
+package telemetry
+
+import (
+ "fmt"
+)
+
+var keyString = fmt.Sprintf("%064b", 0)
+
+// getDummyKeyString returns a dummy key string
+// satisfies the wsrpc key length constraints
+func GetDummyKeyString() string {
+ return keyString
+}
+
+// getDummyKeyString returns a dummy key string with the specified prefix
+// satisfies the wsrpc key length constraints
+func GetDummyKeyStringWithPrefix(prefix string) string {
+ combo := prefix + GetDummyKeyString()
+ return combo[:64]
+}
diff --git a/core/services/versioning/orm.go b/core/services/versioning/orm.go
index 8ed745955dc..5a2472eee8e 100644
--- a/core/services/versioning/orm.go
+++ b/core/services/versioning/orm.go
@@ -7,11 +7,10 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/jackc/pgconn"
- "github.com/jmoiron/sqlx"
"github.com/pkg/errors"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
// Version ORM manages the node_versions table
@@ -19,19 +18,19 @@ import (
// The database version is ONLY useful for managing versioning specific to the database e.g. for backups or migrations
type ORM interface {
- FindLatestNodeVersion() (*NodeVersion, error)
- UpsertNodeVersion(version NodeVersion) error
+ FindLatestNodeVersion(ctx context.Context) (*NodeVersion, error)
+ UpsertNodeVersion(ctx context.Context, version NodeVersion) error
}
type orm struct {
- db *sqlx.DB
+ ds sqlutil.DataSource
lggr logger.Logger
timeout time.Duration
}
-func NewORM(db *sqlx.DB, lggr logger.Logger, timeout time.Duration) *orm {
+func NewORM(ds sqlutil.DataSource, lggr logger.Logger, timeout time.Duration) *orm {
return &orm{
- db: db,
+ ds: ds,
lggr: lggr.Named("VersioningORM"),
timeout: timeout,
}
@@ -41,17 +40,17 @@ func NewORM(db *sqlx.DB, lggr logger.Logger, timeout time.Duration) *orm {
// version is newer than the current one
// NOTE: If you just need the current application version, consider using static.Version instead
// The database version is ONLY useful for managing versioning specific to the database e.g. for backups or migrations
-func (o *orm) UpsertNodeVersion(version NodeVersion) error {
+func (o *orm) UpsertNodeVersion(ctx context.Context, version NodeVersion) error {
now := time.Now()
if _, err := semver.NewVersion(version.Version); err != nil {
return errors.Wrapf(err, "%q is not valid semver", version.Version)
}
- ctx, cancel := context.WithTimeout(context.Background(), o.timeout)
+ ctx, cancel := context.WithTimeout(ctx, o.timeout)
defer cancel()
- return pg.SqlxTransaction(ctx, o.db, o.lggr, func(tx pg.Queryer) error {
- if _, _, err := CheckVersion(tx, logger.NullLogger, version.Version); err != nil {
+ return sqlutil.TransactDataSource(ctx, o.ds, nil, func(tx sqlutil.DataSource) error {
+ if _, _, err := CheckVersion(ctx, tx, logger.NullLogger, version.Version); err != nil {
return err
}
@@ -63,17 +62,17 @@ version = EXCLUDED.version,
created_at = EXCLUDED.created_at
`
- _, err := tx.Exec(stmt, version.Version, now)
+ _, err := tx.ExecContext(ctx, stmt, version.Version, now)
return err
})
}
// CheckVersion returns an error if there is a valid semver version in the
// node_versions table that is higher than the current app version
-func CheckVersion(q pg.Queryer, lggr logger.Logger, appVersion string) (appv, dbv *semver.Version, err error) {
+func CheckVersion(ctx context.Context, ds sqlutil.DataSource, lggr logger.Logger, appVersion string) (appv, dbv *semver.Version, err error) {
lggr = lggr.Named("Version")
var dbVersion string
- err = q.Get(&dbVersion, `SELECT version FROM node_versions ORDER BY created_at DESC LIMIT 1 FOR UPDATE`)
+ err = ds.GetContext(ctx, &dbVersion, `SELECT version FROM node_versions ORDER BY created_at DESC LIMIT 1 FOR UPDATE`)
if errors.Is(err, sql.ErrNoRows) {
lggr.Debugw("No previous version set", "appVersion", appVersion)
return nil, nil, nil
@@ -105,7 +104,7 @@ func CheckVersion(q pg.Queryer, lggr logger.Logger, appVersion string) (appv, db
// FindLatestNodeVersion looks up the latest node version
// NOTE: If you just need the current application version, consider using static.Version instead
// The database version is ONLY useful for managing versioning specific to the database e.g. for backups or migrations
-func (o *orm) FindLatestNodeVersion() (*NodeVersion, error) {
+func (o *orm) FindLatestNodeVersion(ctx context.Context) (*NodeVersion, error) {
stmt := `
SELECT version, created_at
FROM node_versions
@@ -113,7 +112,7 @@ ORDER BY created_at DESC
`
var nodeVersion NodeVersion
- err := o.db.Get(&nodeVersion, stmt)
+ err := o.ds.GetContext(ctx, &nodeVersion, stmt)
if err != nil {
return nil, err
}
diff --git a/core/services/versioning/orm_test.go b/core/services/versioning/orm_test.go
index fe19a2dcd73..f655c9c47fe 100644
--- a/core/services/versioning/orm_test.go
+++ b/core/services/versioning/orm_test.go
@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
@@ -14,13 +15,14 @@ import (
)
func TestORM_NodeVersion_UpsertNodeVersion(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
orm := NewORM(db, logger.TestLogger(t), pg.DefaultQueryTimeout)
- err := orm.UpsertNodeVersion(NewNodeVersion("9.9.8"))
+ err := orm.UpsertNodeVersion(ctx, NewNodeVersion("9.9.8"))
require.NoError(t, err)
- ver, err := orm.FindLatestNodeVersion()
+ ver, err := orm.FindLatestNodeVersion(ctx)
require.NoError(t, err)
require.NotNil(t, ver)
@@ -28,85 +30,87 @@ func TestORM_NodeVersion_UpsertNodeVersion(t *testing.T) {
require.NotZero(t, ver.CreatedAt)
// Testing Upsert
- require.NoError(t, orm.UpsertNodeVersion(NewNodeVersion("9.9.8")))
+ require.NoError(t, orm.UpsertNodeVersion(ctx, NewNodeVersion("9.9.8")))
- err = orm.UpsertNodeVersion(NewNodeVersion("9.9.7"))
+ err = orm.UpsertNodeVersion(ctx, NewNodeVersion("9.9.7"))
require.Error(t, err)
assert.Contains(t, err.Error(), "Application version (9.9.7) is lower than database version (9.9.8). Only Chainlink 9.9.8 or higher can be run on this database")
- require.NoError(t, orm.UpsertNodeVersion(NewNodeVersion("9.9.9")))
+ require.NoError(t, orm.UpsertNodeVersion(ctx, NewNodeVersion("9.9.9")))
var count int
err = db.QueryRowx(`SELECT count(*) FROM node_versions`).Scan(&count)
require.NoError(t, err)
assert.Equal(t, 1, count)
- ver, err = orm.FindLatestNodeVersion()
+ ver, err = orm.FindLatestNodeVersion(ctx)
require.NoError(t, err)
require.NotNil(t, ver)
require.Equal(t, "9.9.9", ver.Version)
// invalid semver returns error
- err = orm.UpsertNodeVersion(NewNodeVersion("random_12345"))
+ err = orm.UpsertNodeVersion(ctx, NewNodeVersion("random_12345"))
require.Error(t, err)
assert.Contains(t, err.Error(), "\"random_12345\" is not valid semver: Invalid Semantic Version")
- ver, err = orm.FindLatestNodeVersion()
+ ver, err = orm.FindLatestNodeVersion(ctx)
require.NoError(t, err)
require.NotNil(t, ver)
require.Equal(t, "9.9.9", ver.Version)
}
func Test_Version_CheckVersion(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
lggr := logger.TestLogger(t)
orm := NewORM(db, lggr, pg.DefaultQueryTimeout)
- err := orm.UpsertNodeVersion(NewNodeVersion("9.9.8"))
+ err := orm.UpsertNodeVersion(ctx, NewNodeVersion("9.9.8"))
require.NoError(t, err)
// invalid app version semver returns error
- _, _, err = CheckVersion(db, lggr, static.Unset)
+ _, _, err = CheckVersion(ctx, db, lggr, static.Unset)
require.Error(t, err)
assert.Contains(t, err.Error(), `Application version "unset" is not valid semver`)
- _, _, err = CheckVersion(db, lggr, "some old bollocks")
+ _, _, err = CheckVersion(ctx, db, lggr, "some old bollocks")
require.Error(t, err)
assert.Contains(t, err.Error(), `Application version "some old bollocks" is not valid semver`)
// lower version returns error
- _, _, err = CheckVersion(db, lggr, "9.9.7")
+ _, _, err = CheckVersion(ctx, db, lggr, "9.9.7")
require.Error(t, err)
assert.Contains(t, err.Error(), "Application version (9.9.7) is lower than database version (9.9.8). Only Chainlink 9.9.8 or higher can be run on this database")
// equal version is ok
var appv, dbv *semver.Version
- appv, dbv, err = CheckVersion(db, lggr, "9.9.8")
+ appv, dbv, err = CheckVersion(ctx, db, lggr, "9.9.8")
require.NoError(t, err)
assert.Equal(t, "9.9.8", appv.String())
assert.Equal(t, "9.9.8", dbv.String())
// greater version is ok
- appv, dbv, err = CheckVersion(db, lggr, "9.9.9")
+ appv, dbv, err = CheckVersion(ctx, db, lggr, "9.9.9")
require.NoError(t, err)
assert.Equal(t, "9.9.9", appv.String())
assert.Equal(t, "9.9.8", dbv.String())
}
func TestORM_NodeVersion_FindLatestNodeVersion(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
orm := NewORM(db, logger.TestLogger(t), pg.DefaultQueryTimeout)
// Not Found
- _, err := orm.FindLatestNodeVersion()
+ _, err := orm.FindLatestNodeVersion(ctx)
require.Error(t, err)
- err = orm.UpsertNodeVersion(NewNodeVersion("9.9.8"))
+ err = orm.UpsertNodeVersion(ctx, NewNodeVersion("9.9.8"))
require.NoError(t, err)
- ver, err := orm.FindLatestNodeVersion()
+ ver, err := orm.FindLatestNodeVersion(ctx)
require.NoError(t, err)
require.NotNil(t, ver)
diff --git a/core/services/vrf/delegate.go b/core/services/vrf/delegate.go
index 617a28ac4d5..c5b4df3f811 100644
--- a/core/services/vrf/delegate.go
+++ b/core/services/vrf/delegate.go
@@ -2,6 +2,7 @@ package vrf
import (
"context"
+ "encoding/json"
"fmt"
"time"
@@ -11,8 +12,7 @@ import (
"github.com/theodesp/go-heaps/pairing"
"go.uber.org/multierr"
- "github.com/jmoiron/sqlx"
-
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/log"
@@ -26,7 +26,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
v1 "github.com/smartcontractkit/chainlink/v2/core/services/vrf/v1"
v2 "github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2"
@@ -34,7 +33,7 @@ import (
)
type Delegate struct {
- q pg.Q
+ ds sqlutil.DataSource
pr pipeline.Runner
porm pipeline.ORM
ks keystore.Master
@@ -44,16 +43,15 @@ type Delegate struct {
}
func NewDelegate(
- db *sqlx.DB,
+ ds sqlutil.DataSource,
ks keystore.Master,
pr pipeline.Runner,
porm pipeline.ORM,
legacyChains legacyevm.LegacyChainContainer,
lggr logger.Logger,
- cfg pg.QConfig,
mailMon *mailbox.Monitor) *Delegate {
return &Delegate{
- q: pg.NewQ(db, lggr, cfg),
+ ds: ds,
ks: ks,
pr: pr,
porm: porm,
@@ -67,16 +65,29 @@ func (d *Delegate) JobType() job.Type {
return job.VRF
}
-func (d *Delegate) BeforeJobCreated(job.Job) {}
-func (d *Delegate) AfterJobCreated(job.Job) {}
-func (d *Delegate) BeforeJobDeleted(job.Job) {}
-func (d *Delegate) OnDeleteJob(context.Context, job.Job, pg.Queryer) error { return nil }
+func (d *Delegate) BeforeJobCreated(job.Job) {}
+func (d *Delegate) AfterJobCreated(job.Job) {}
+func (d *Delegate) BeforeJobDeleted(job.Job) {}
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec satisfies the job.Delegate interface.
func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.ServiceCtx, error) {
if jb.VRFSpec == nil || jb.PipelineSpec == nil {
return nil, errors.Errorf("vrf.Delegate expects a VRFSpec and PipelineSpec to be present, got %+v", jb)
}
+ marshalledVRFSpec, err := json.MarshalIndent(jb.VRFSpec, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ marshalledPipelineSpec, err := json.MarshalIndent(jb.PipelineSpec, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ d.lggr.Debugw("Creating services for job spec",
+ "vrfSpec", string(marshalledVRFSpec),
+ "pipelineSpec", string(marshalledPipelineSpec),
+ "keyHash", jb.VRFSpec.PublicKey.MustHash(),
+ )
pl, err := jb.PipelineSpec.ParsePipeline()
if err != nil {
return nil, err
@@ -171,7 +182,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi
lV2Plus,
chain,
chain.ID(),
- d.q,
+ d.ds,
v2.NewCoordinatorV2_5(coordinatorV2Plus),
batchCoordinatorV2,
vrfOwner,
@@ -225,7 +236,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi
lV2,
chain,
chain.ID(),
- d.q,
+ d.ds,
v2.NewCoordinatorV2(coordinatorV2),
batchCoordinatorV2,
vrfOwner,
@@ -246,7 +257,6 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi
Cfg: chain.Config().EVM(),
FeeCfg: chain.Config().EVM().GasEstimator(),
L: logger.Sugared(lV1),
- Q: d.q,
Coordinator: coordinator,
PipelineRunner: d.pr,
GethKs: d.ks.Eth(),
diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go
index adf54428b4e..db9724179e7 100644
--- a/core/services/vrf/delegate_test.go
+++ b/core/services/vrf/delegate_test.go
@@ -78,8 +78,8 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv
hb := headtracker.NewHeadBroadcaster(lggr)
// Don't mock db interactions
- prm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- btORM := bridges.NewORM(db, lggr, cfg.Database())
+ prm := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns())
+ btORM := bridges.NewORM(db)
ks := keystore.NewInMemory(db, utils.FastScryptParams, lggr, cfg.Database())
_, dbConfig, evmConfig := txmgr.MakeTestConfigs(t)
txm, err := txmgr.NewTxm(db, db, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), dbConfig, dbConfig.Listener(), ec, logger.TestLogger(t), nil, ks.Eth(), nil)
@@ -160,7 +160,6 @@ func setup(t *testing.T) (vrfUniverse, *v1.Listener, job.Job) {
vuni.prm,
vuni.legacyChains,
logger.TestLogger(t),
- cfg.Database(),
mailMon)
vs := testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{PublicKey: vuni.vrfkey.PublicKey.String(), EVMChainID: testutils.FixtureChainID.String()})
jb, err := vrfcommon.ValidatedVRFSpec(vs.Toml())
@@ -201,9 +200,10 @@ func TestDelegate_ReorgAttackProtection(t *testing.T) {
preSeed := common.BigToHash(big.NewInt(42)).Bytes()
txHash := evmutils.NewHash()
vuni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil).Maybe()
- vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil).Maybe()
+ vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil).Maybe()
vuni.ec.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(generateCallbackReturnValues(t, false), nil).Maybe()
- listener.HandleLog(log.NewLogBroadcast(types.Log{
+ ctx := testutils.Context(t)
+ listener.HandleLog(ctx, log.NewLogBroadcast(types.Log{
// Data has all the NON-indexed parameters
Data: bytes.Join([][]byte{pk.MustHash().Bytes(), // key hash
preSeed, // preSeed
@@ -302,14 +302,15 @@ func TestDelegate_ValidLog(t *testing.T) {
consumed := make(chan struct{})
for i, tc := range tt {
tc := tc
+ ctx := testutils.Context(t)
vuni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
consumed <- struct{}{}
}).Return(nil).Once()
// Expect a call to check if the req is already fulfilled.
vuni.ec.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(generateCallbackReturnValues(t, false), nil)
- listener.HandleLog(log.NewLogBroadcast(tc.log, vuni.cid, nil))
+ listener.HandleLog(ctx, log.NewLogBroadcast(tc.log, vuni.cid, nil))
// Wait until the log is present
waitForChannel(t, added, time.Second, "request not added to the queue")
// Feed it a head which confirms it.
@@ -318,7 +319,7 @@ func TestDelegate_ValidLog(t *testing.T) {
// Ensure we created a successful run.
waitForChannel(t, runComplete, 2*time.Second, "pipeline not complete")
- runs, err := vuni.prm.GetAllRuns()
+ runs, err := vuni.prm.GetAllRuns(ctx)
require.NoError(t, err)
require.Equal(t, i+1, len(runs))
assert.False(t, runs[0].FatalErrors.HasError())
@@ -328,13 +329,13 @@ func TestDelegate_ValidLog(t *testing.T) {
p, err := vuni.ks.VRF().GenerateProof(keyID, evmutils.MustHash(string(bytes.Join([][]byte{preSeed, bh.Bytes()}, []byte{}))).Big())
require.NoError(t, err)
vuni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
- vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
consumed <- struct{}{}
}).Return(nil).Once()
// If we send a completed log we should the respCount increase
var reqIDBytes []byte
copy(reqIDBytes[:], tc.reqID[:])
- listener.HandleLog(log.NewLogBroadcast(types.Log{
+ listener.HandleLog(ctx, log.NewLogBroadcast(types.Log{
// Data has all the NON-indexed parameters
Data: bytes.Join([][]byte{reqIDBytes, // output
p.Output.Bytes(),
@@ -354,7 +355,7 @@ func TestDelegate_InvalidLog(t *testing.T) {
vuni, listener, jb := setup(t)
vuni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
done := make(chan struct{})
- vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
done <- struct{}{}
}).Return(nil).Once()
// Expect a call to check if the req is already fulfilled.
@@ -365,7 +366,8 @@ func TestDelegate_InvalidLog(t *testing.T) {
added <- struct{}{}
})
// Send an invalid log (keyhash doesnt match)
- listener.HandleLog(log.NewLogBroadcast(types.Log{
+ ctx := testutils.Context(t)
+ listener.HandleLog(ctx, log.NewLogBroadcast(types.Log{
// Data has all the NON-indexed parameters
Data: append(append(append(append(
evmutils.NewHash().Bytes(), // key hash
@@ -392,7 +394,7 @@ func TestDelegate_InvalidLog(t *testing.T) {
waitForChannel(t, done, time.Second, "log not consumed")
// Should create a run that errors in the vrf task
- runs, err := vuni.prm.GetAllRuns()
+ runs, err := vuni.prm.GetAllRuns(ctx)
require.NoError(t, err)
require.Equal(t, len(runs), 1)
for _, tr := range runs[0].PipelineTaskRuns {
@@ -417,7 +419,7 @@ func TestFulfilledCheck(t *testing.T) {
vuni, listener, jb := setup(t)
vuni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
done := make(chan struct{})
- vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+ vuni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
done <- struct{}{}
}).Return(nil).Once()
// Expect a call to check if the req is already fulfilled.
@@ -429,7 +431,8 @@ func TestFulfilledCheck(t *testing.T) {
added <- struct{}{}
})
// Send an invalid log (keyhash doesn't match)
- listener.HandleLog(log.NewLogBroadcast(
+ ctx := testutils.Context(t)
+ listener.HandleLog(ctx, log.NewLogBroadcast(
types.Log{
// Data has all the NON-indexed parameters
Data: bytes.Join([][]byte{
@@ -455,7 +458,7 @@ func TestFulfilledCheck(t *testing.T) {
waitForChannel(t, done, time.Second, "log not consumed")
// Should consume the log with no run
- runs, err := vuni.prm.GetAllRuns()
+ runs, err := vuni.prm.GetAllRuns(ctx)
require.NoError(t, err)
require.Equal(t, len(runs), 0)
}
@@ -685,7 +688,6 @@ func Test_VRFV2PlusServiceFailsWhenVRFOwnerProvided(t *testing.T) {
vuni.prm,
vuni.legacyChains,
logger.TestLogger(t),
- cfg.Database(),
mailMon)
chain, err := vuni.legacyChains.Get(testutils.FixtureChainID.String())
require.NoError(t, err)
diff --git a/core/services/vrf/v1/integration_test.go b/core/services/vrf/v1/integration_test.go
index f68700a8af7..1d11615950b 100644
--- a/core/services/vrf/v1/integration_test.go
+++ b/core/services/vrf/v1/integration_test.go
@@ -45,6 +45,7 @@ func TestIntegration_VRF_JPV2(t *testing.T) {
for _, tt := range tests {
test := tt
t.Run(test.name, func(t *testing.T) {
+ ctx := testutils.Context(t)
config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].GasEstimator.EIP1559DynamicFees = &test.eip1559
c.EVM[0].ChainID = (*ubig.Big)(testutils.SimulatedChainID)
@@ -75,7 +76,7 @@ func TestIntegration_VRF_JPV2(t *testing.T) {
}
var runs []pipeline.Run
gomega.NewWithT(t).Eventually(func() bool {
- runs, err = app.PipelineORM().GetAllRuns()
+ runs, err = app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
// It possible that we send the test request
// before the Job spawner has started the vrf services, which is fine
@@ -128,6 +129,7 @@ func TestIntegration_VRF_JPV2(t *testing.T) {
func TestIntegration_VRF_WithBHS(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true)
c.EVM[0].BlockBackfillDepth = ptr[uint32](500)
@@ -196,7 +198,7 @@ func TestIntegration_VRF_WithBHS(t *testing.T) {
var runs []pipeline.Run
gomega.NewWithT(t).Eventually(func() bool {
- runs, err = app.PipelineORM().GetAllRuns()
+ runs, err = app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
cu.Backend.Commit()
return len(runs) == 1 && runs[0].State == pipeline.RunStatusCompleted
diff --git a/core/services/vrf/v1/listener_v1.go b/core/services/vrf/v1/listener_v1.go
index c57265634e5..ddf5779deb0 100644
--- a/core/services/vrf/v1/listener_v1.go
+++ b/core/services/vrf/v1/listener_v1.go
@@ -17,6 +17,7 @@ import (
"github.com/theodesp/go-heaps/pairing"
"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-common/pkg/utils/mathutil"
@@ -303,17 +304,16 @@ func (lsn *Listener) RunLogListener(unsubscribes []func(), minConfs uint32) {
break
}
recovery.WrapRecover(lsn.L, func() {
- lsn.handleLog(lb, minConfs)
+ ctx, cancel := lsn.ChStop.NewCtx()
+ defer cancel()
+ lsn.handleLog(ctx, lb, minConfs)
})
}
}
}
}
-func (lsn *Listener) handleLog(lb log.Broadcast, minConfs uint32) {
- ctx, cancel := lsn.ChStop.NewCtx()
- defer cancel()
-
+func (lsn *Listener) handleLog(ctx context.Context, lb log.Broadcast, minConfs uint32) {
lggr := lsn.L.With(
"log", lb.String(),
"decodedLog", lb.DecodedLog(),
@@ -380,7 +380,7 @@ func (lsn *Listener) shouldProcessLog(ctx context.Context, lb log.Broadcast) boo
}
func (lsn *Listener) markLogAsConsumed(ctx context.Context, lb log.Broadcast) {
- err := lsn.Chain.LogBroadcaster().MarkConsumed(ctx, lb)
+ err := lsn.Chain.LogBroadcaster().MarkConsumed(ctx, nil, lb)
lsn.L.ErrorIf(err, fmt.Sprintf("Unable to mark log %v as consumed", lb.String()))
}
@@ -486,9 +486,10 @@ func (lsn *Listener) ProcessRequest(ctx context.Context, req request) bool {
run := pipeline.NewRun(*lsn.Job.PipelineSpec, vars)
// The VRF pipeline has no async tasks, so we don't need to check for `incomplete`
- if _, err = lsn.PipelineRunner.Run(ctx, run, lggr, true, func(tx pg.Queryer) error {
+ if _, err = lsn.PipelineRunner.Run(ctx, run, lggr, true, func(tx sqlutil.DataSource) error {
// Always mark consumed regardless of whether the proof failed or not.
- if err = lsn.Chain.LogBroadcaster().MarkConsumed(ctx, req.lb); err != nil {
+ //TODO restore tx https://smartcontract-it.atlassian.net/browse/BCF-2978
+ if err = lsn.Chain.LogBroadcaster().MarkConsumed(ctx, nil, req.lb); err != nil {
lggr.Errorw("Failed mark consumed", "err", err)
}
return nil
@@ -525,7 +526,7 @@ func (lsn *Listener) Close() error {
})
}
-func (lsn *Listener) HandleLog(lb log.Broadcast) {
+func (lsn *Listener) HandleLog(ctx context.Context, lb log.Broadcast) {
if !lsn.Deduper.ShouldDeliver(lb.RawLog()) {
lsn.L.Tracew("skipping duplicate log broadcast", "log", lb.RawLog())
return
diff --git a/core/services/vrf/v2/integration_helpers_test.go b/core/services/vrf/v2/integration_helpers_test.go
index f19f39f03f2..3d7a94ae833 100644
--- a/core/services/vrf/v2/integration_helpers_test.go
+++ b/core/services/vrf/v2/integration_helpers_test.go
@@ -62,6 +62,7 @@ func testSingleConsumerHappyPath(
rwfe v22.RandomWordsFulfilled,
subID *big.Int),
) {
+ ctx := testutils.Context(t)
key1 := cltest.MustGenerateRandomKey(t)
key2 := cltest.MustGenerateRandomKey(t)
gasLanePriceWei := assets.GWei(10)
@@ -87,7 +88,7 @@ func testSingleConsumerHappyPath(
// Fund gas lanes.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
sendEth(t, ownerKey, uni.backend, key2.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job using key1 and key2 on the same gas lane.
jbs := createVRFJobs(
@@ -111,7 +112,7 @@ func testSingleConsumerHappyPath(
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -133,7 +134,7 @@ func testSingleConsumerHappyPath(
requestID2, _ := requestRandomnessAndAssertRandomWordsRequestedEvent(t, consumerContract, consumer, keyHash, subID, numWords, 500_000, coordinator, uni.backend, nativePayment)
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 2
@@ -153,11 +154,11 @@ func testSingleConsumerHappyPath(
assertNumRandomWords(t, consumerContract, numWords)
// Assert that both send addresses were used to fulfill the requests
- n, err := uni.backend.PendingNonceAt(testutils.Context(t), key1.Address)
+ n, err := uni.backend.PendingNonceAt(ctx, key1.Address)
require.NoError(t, err)
require.EqualValues(t, 1, n)
- n, err = uni.backend.PendingNonceAt(testutils.Context(t), key2.Address)
+ n, err = uni.backend.PendingNonceAt(ctx, key2.Address)
require.NoError(t, err)
require.EqualValues(t, 1, n)
@@ -182,6 +183,7 @@ func testMultipleConsumersNeedBHS(
coordinator v22.CoordinatorV2_X,
rwfe v22.RandomWordsFulfilled),
) {
+ ctx := testutils.Context(t)
nConsumers := len(consumers)
vrfKey := cltest.MustGenerateRandomKey(t)
sendEth(t, ownerKey, uni.backend, vrfKey.Address, 10)
@@ -216,7 +218,7 @@ func testMultipleConsumersNeedBHS(
})
keys = append(keys, ownerKey, vrfKey)
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, keys...)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
vrfJobs := createVRFJobs(
@@ -250,7 +252,7 @@ func testMultipleConsumersNeedBHS(
// Ensure log poller is ready and has all logs.
require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready())
- require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), 1))
+ require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(ctx, 1))
for i := 0; i < nConsumers; i++ {
consumer := consumers[i]
@@ -284,7 +286,7 @@ func testMultipleConsumersNeedBHS(
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -320,6 +322,7 @@ func testMultipleConsumersNeedTrustedBHS(
coordinator v22.CoordinatorV2_X,
rwfe v22.RandomWordsFulfilled),
) {
+ ctx := testutils.Context(t)
nConsumers := len(consumers)
vrfKey := cltest.MustGenerateRandomKey(t)
sendEth(t, ownerKey, uni.backend, vrfKey.Address, 10)
@@ -364,7 +367,7 @@ func testMultipleConsumersNeedTrustedBHS(
})
keys = append(keys, ownerKey, vrfKey)
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, keys...)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
vrfJobs := createVRFJobs(
@@ -403,7 +406,7 @@ func testMultipleConsumersNeedTrustedBHS(
// Ensure log poller is ready and has all logs.
chain := app.GetRelayers().LegacyEVMChains().Slice()[0]
require.NoError(t, chain.LogPoller().Ready())
- require.NoError(t, chain.LogPoller().Replay(testutils.Context(t), 1))
+ require.NoError(t, chain.LogPoller().Replay(ctx, 1))
for i := 0; i < nConsumers; i++ {
consumer := consumers[i]
@@ -445,7 +448,7 @@ func testMultipleConsumersNeedTrustedBHS(
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -534,6 +537,7 @@ func testSingleConsumerHappyPathBatchFulfillment(
rwfe v22.RandomWordsFulfilled,
subID *big.Int),
) {
+ ctx := testutils.Context(t)
key1 := cltest.MustGenerateRandomKey(t)
gasLanePriceWei := assets.GWei(10)
config, db := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
@@ -555,7 +559,7 @@ func testSingleConsumerHappyPathBatchFulfillment(
// Fund gas lane.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job using key1 and key2 on the same gas lane.
jbs := createVRFJobs(
@@ -590,7 +594,7 @@ func testSingleConsumerHappyPathBatchFulfillment(
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
if bigGasCallback {
@@ -640,6 +644,7 @@ func testSingleConsumerNeedsTopUp(
coordinator v22.CoordinatorV2_X,
rwfe v22.RandomWordsFulfilled),
) {
+ ctx := testutils.Context(t)
key := cltest.MustGenerateRandomKey(t)
gasLanePriceWei := assets.GWei(1000)
config, db := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
@@ -659,7 +664,7 @@ func testSingleConsumerNeedsTopUp(
// Fund expensive gas lane.
sendEth(t, ownerKey, uni.backend, key.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
jbs := createVRFJobs(
@@ -682,7 +687,7 @@ func testSingleConsumerNeedsTopUp(
// Fulfillment will not be enqueued because subscriber doesn't have enough LINK.
gomega.NewGomegaWithT(t).Consistently(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("assert 1", "runs", len(runs))
return len(runs) == 0
@@ -695,7 +700,7 @@ func testSingleConsumerNeedsTopUp(
// Wait for fulfillment to go through.
gomega.NewWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("assert 2", "runs", len(runs))
return len(runs) == 1
@@ -737,6 +742,7 @@ func testBlockHeaderFeeder(
coordinator v22.CoordinatorV2_X,
rwfe v22.RandomWordsFulfilled),
) {
+ ctx := testutils.Context(t)
nConsumers := len(consumers)
vrfKey := cltest.MustGenerateRandomKey(t)
@@ -760,7 +766,7 @@ func testBlockHeaderFeeder(
c.EVM[0].FinalityDepth = ptr[uint32](2)
})
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, vrfKey, bhfKey)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
vrfJobs := createVRFJobs(
@@ -792,7 +798,7 @@ func testBlockHeaderFeeder(
// Ensure log poller is ready and has all logs.
require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready())
- require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), 1))
+ require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(ctx, 1))
for i := 0; i < nConsumers; i++ {
consumer := consumers[i]
@@ -821,7 +827,7 @@ func testBlockHeaderFeeder(
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -900,6 +906,7 @@ func testSingleConsumerForcedFulfillment(
batchEnabled bool,
vrfVersion vrfcommon.Version,
) {
+ ctx := testutils.Context(t)
key1 := cltest.MustGenerateRandomKey(t)
key2 := cltest.MustGenerateRandomKey(t)
gasLanePriceWei := assets.GWei(10)
@@ -951,7 +958,7 @@ func testSingleConsumerForcedFulfillment(
// Fund gas lanes.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
sendEth(t, ownerKey, uni.backend, key2.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job using key1 and key2 on the same gas lane.
jbs := createVRFJobs(
@@ -1065,6 +1072,7 @@ func testSingleConsumerEIP150(
vrfVersion vrfcommon.Version,
nativePayment bool,
) {
+ ctx := testutils.Context(t)
callBackGasLimit := int64(2_500_000) // base callback gas.
key1 := cltest.MustGenerateRandomKey(t)
@@ -1090,7 +1098,7 @@ func testSingleConsumerEIP150(
// Fund gas lane.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
jbs := createVRFJobs(
@@ -1114,7 +1122,7 @@ func testSingleConsumerEIP150(
// Wait for simulation to pass.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -1132,6 +1140,7 @@ func testSingleConsumerEIP150Revert(
vrfVersion vrfcommon.Version,
nativePayment bool,
) {
+ ctx := testutils.Context(t)
callBackGasLimit := int64(2_500_000) // base callback gas.
eip150Fee := int64(0) // no premium given for callWithExactGas
coordinatorFulfillmentOverhead := int64(90_000) // fixed gas used in coordinator fulfillment
@@ -1160,7 +1169,7 @@ func testSingleConsumerEIP150Revert(
// Fund gas lane.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
jbs := createVRFJobs(
@@ -1184,7 +1193,7 @@ func testSingleConsumerEIP150Revert(
// Simulation should not pass.
gomega.NewGomegaWithT(t).Consistently(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 0
@@ -1202,6 +1211,7 @@ func testSingleConsumerBigGasCallbackSandwich(
vrfVersion vrfcommon.Version,
nativePayment bool,
) {
+ ctx := testutils.Context(t)
key1 := cltest.MustGenerateRandomKey(t)
gasLanePriceWei := assets.GWei(100)
config, db := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
@@ -1224,7 +1234,7 @@ func testSingleConsumerBigGasCallbackSandwich(
// Fund gas lane.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
jbs := createVRFJobs(
@@ -1253,7 +1263,7 @@ func testSingleConsumerBigGasCallbackSandwich(
// Assert that we've completed 0 runs before adding 3 new requests.
{
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
assert.Equal(t, 0, len(runs))
assert.Equal(t, 3, len(reqIDs))
@@ -1262,7 +1272,7 @@ func testSingleConsumerBigGasCallbackSandwich(
// Wait for the 50_000 gas randomness request to be enqueued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -1271,7 +1281,7 @@ func testSingleConsumerBigGasCallbackSandwich(
// After the first successful request, no more will be enqueued.
gomega.NewGomegaWithT(t).Consistently(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("assert 1", "runs", len(runs))
return len(runs) == 1
@@ -1285,7 +1295,7 @@ func testSingleConsumerBigGasCallbackSandwich(
// Assert that we've still only completed 1 run before adding new requests.
{
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
assert.Equal(t, 1, len(runs))
}
@@ -1300,7 +1310,7 @@ func testSingleConsumerBigGasCallbackSandwich(
// Fulfillment will not be enqueued because subscriber doesn't have enough LINK for any of the requests.
gomega.NewGomegaWithT(t).Consistently(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("assert 1", "runs", len(runs))
return len(runs) == 1
@@ -1318,6 +1328,7 @@ func testSingleConsumerMultipleGasLanes(
vrfVersion vrfcommon.Version,
nativePayment bool,
) {
+ ctx := testutils.Context(t)
cheapKey := cltest.MustGenerateRandomKey(t)
expensiveKey := cltest.MustGenerateRandomKey(t)
cheapGasLane := assets.GWei(10)
@@ -1349,7 +1360,7 @@ func testSingleConsumerMultipleGasLanes(
// Fund gas lanes.
sendEth(t, ownerKey, uni.backend, cheapKey.Address, 10)
sendEth(t, ownerKey, uni.backend, expensiveKey.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF jobs.
jbs := createVRFJobs(
@@ -1374,7 +1385,7 @@ func testSingleConsumerMultipleGasLanes(
// Wait for fulfillment to be queued for cheap key hash.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("assert 1", "runs", len(runs))
return len(runs) == 1
@@ -1394,7 +1405,7 @@ func testSingleConsumerMultipleGasLanes(
// We should not have any new fulfillments until a top up.
gomega.NewWithT(t).Consistently(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("assert 2", "runs", len(runs))
return len(runs) == 1
@@ -1406,7 +1417,7 @@ func testSingleConsumerMultipleGasLanes(
// Wait for fulfillment to be queued for expensive key hash.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("assert 1", "runs", len(runs))
return len(runs) == 2
@@ -1442,6 +1453,7 @@ func testSingleConsumerAlwaysRevertingCallbackStillFulfilled(
vrfVersion vrfcommon.Version,
nativePayment bool,
) {
+ ctx := testutils.Context(t)
key := cltest.MustGenerateRandomKey(t)
gasLanePriceWei := assets.GWei(10)
config, db := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
@@ -1464,7 +1476,7 @@ func testSingleConsumerAlwaysRevertingCallbackStillFulfilled(
// Fund gas lane.
sendEth(t, ownerKey, uni.backend, key.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
jbs := createVRFJobs(
@@ -1488,7 +1500,7 @@ func testSingleConsumerAlwaysRevertingCallbackStillFulfilled(
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -1511,6 +1523,7 @@ func testConsumerProxyHappyPath(
vrfVersion vrfcommon.Version,
nativePayment bool,
) {
+ ctx := testutils.Context(t)
key1 := cltest.MustGenerateRandomKey(t)
key2 := cltest.MustGenerateRandomKey(t)
gasLanePriceWei := assets.GWei(10)
@@ -1540,7 +1553,7 @@ func testConsumerProxyHappyPath(
// Create gas lane.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
sendEth(t, ownerKey, uni.backend, key2.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job using key1 and key2 on the same gas lane.
jbs := createVRFJobs(
@@ -1565,7 +1578,7 @@ func testConsumerProxyHappyPath(
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -1591,7 +1604,7 @@ func testConsumerProxyHappyPath(
t, consumerContract, consumerOwner, keyHash, subID, numWords, 750_000, uni.rootContract, uni.backend, nativePayment)
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 2
@@ -1603,11 +1616,11 @@ func testConsumerProxyHappyPath(
assertNumRandomWords(t, consumerContract, numWords)
// Assert that both send addresses were used to fulfill the requests
- n, err := uni.backend.PendingNonceAt(testutils.Context(t), key1.Address)
+ n, err := uni.backend.PendingNonceAt(ctx, key1.Address)
require.NoError(t, err)
require.EqualValues(t, 1, n)
- n, err = uni.backend.PendingNonceAt(testutils.Context(t), key2.Address)
+ n, err = uni.backend.PendingNonceAt(ctx, key2.Address)
require.NoError(t, err)
require.EqualValues(t, 1, n)
@@ -1644,6 +1657,7 @@ func testMaliciousConsumer(
batchEnabled bool,
vrfVersion vrfcommon.Version,
) {
+ ctx := testutils.Context(t)
config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](2_000_000)
c.EVM[0].GasEstimator.PriceMax = assets.GWei(1)
@@ -1656,7 +1670,7 @@ func testMaliciousConsumer(
carol := uni.vrfConsumers[0]
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
err := app.GetKeyStore().Unlock(cltest.Password)
require.NoError(t, err)
@@ -1702,7 +1716,7 @@ func testMaliciousConsumer(
// by the node.
var attempts []txmgr.TxAttempt
gomega.NewWithT(t).Eventually(func() bool {
- attempts, _, err = app.TxmStorageService().TxAttempts(testutils.Context(t), 0, 1000)
+ attempts, _, err = app.TxmStorageService().TxAttempts(ctx, 0, 1000)
require.NoError(t, err)
// It possible that we send the test request
// before the job spawner has started the vrf services, which is fine
@@ -1716,7 +1730,7 @@ func testMaliciousConsumer(
// The fulfillment tx should succeed
ch, err := app.GetRelayers().LegacyEVMChains().Get(evmtest.MustGetDefaultChainID(t, config.EVMConfigs()).String())
require.NoError(t, err)
- r, err := ch.Client().TransactionReceipt(testutils.Context(t), attempts[0].Hash)
+ r, err := ch.Client().TransactionReceipt(ctx, attempts[0].Hash)
require.NoError(t, err)
require.Equal(t, uint64(1), r.Status)
@@ -1759,6 +1773,7 @@ func testReplayOldRequestsOnStartUp(
rwfe v22.RandomWordsFulfilled,
subID *big.Int),
) {
+ ctx := testutils.Context(t)
sendingKey := cltest.MustGenerateRandomKey(t)
gasLanePriceWei := assets.GWei(10)
config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
@@ -1778,7 +1793,7 @@ func testReplayOldRequestsOnStartUp(
// Fund gas lanes.
sendEth(t, ownerKey, uni.backend, sendingKey.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF Key, register it to coordinator and export
vrfkey, err := app.GetKeyStore().VRF().Create()
@@ -1816,7 +1831,7 @@ func testReplayOldRequestsOnStartUp(
// Start a new app and create VRF job using the same VRF key created above
app = cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, sendingKey)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
vrfKey, err := app.GetKeyStore().VRF().Import(encodedVrfKey, testutils.Password)
require.NoError(t, err)
@@ -1863,7 +1878,7 @@ func testReplayOldRequestsOnStartUp(
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go
index bfec76afec3..742ff99071c 100644
--- a/core/services/vrf/v2/integration_v2_plus_test.go
+++ b/core/services/vrf/v2/integration_v2_plus_test.go
@@ -1141,6 +1141,7 @@ func setupSubscriptionAndFund(
func TestVRFV2PlusIntegration_Migration(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
ownerKey := cltest.MustGenerateRandomKey(t)
uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false)
key1 := cltest.MustGenerateRandomKey(t)
@@ -1200,7 +1201,7 @@ func TestVRFV2PlusIntegration_Migration(t *testing.T) {
// Wait for fulfillment to be queued.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 1
diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go
index 1a7c15a2508..0c81c3faca5 100644
--- a/core/services/vrf/v2/integration_v2_test.go
+++ b/core/services/vrf/v2/integration_v2_test.go
@@ -73,7 +73,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
"github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1"
@@ -466,7 +465,8 @@ func deployOldCoordinator(
// Send eth from prefunded account.
// Amount is number of ETH not wei.
func sendEth(t *testing.T, key ethkey.KeyV2, ec *backends.SimulatedBackend, to common.Address, eth int) {
- nonce, err := ec.PendingNonceAt(testutils.Context(t), key.Address)
+ ctx := testutils.Context(t)
+ nonce, err := ec.PendingNonceAt(ctx, key.Address)
require.NoError(t, err)
tx := gethtypes.NewTx(&gethtypes.DynamicFeeTx{
ChainID: testutils.SimulatedChainID,
@@ -480,7 +480,7 @@ func sendEth(t *testing.T, key ethkey.KeyV2, ec *backends.SimulatedBackend, to c
})
signedTx, err := gethtypes.SignTx(tx, gethtypes.NewLondonSigner(testutils.SimulatedChainID), key.ToEcdsaPrivKey())
require.NoError(t, err)
- err = ec.SendTransaction(testutils.Context(t), signedTx)
+ err = ec.SendTransaction(ctx, signedTx)
require.NoError(t, err)
ec.Commit()
}
@@ -996,7 +996,9 @@ func testEoa(
batchingEnabled bool,
batchCoordinatorAddress common.Address,
vrfOwnerAddress *common.Address,
- vrfVersion vrfcommon.Version) {
+ vrfVersion vrfcommon.Version,
+) {
+ ctx := testutils.Context(t)
gasLimit := int64(2_500_000)
finalityDepth := uint32(50)
@@ -1030,7 +1032,7 @@ func testEoa(
// Fund gas lane.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
jbs := createVRFJobs(
@@ -1059,7 +1061,7 @@ func testEoa(
// Ensure request is not fulfilled.
gomega.NewGomegaWithT(t).Consistently(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 0
@@ -1069,10 +1071,9 @@ func testEoa(
var broadcastsBeforeFinality []evmlogger.LogBroadcast
var broadcastsAfterFinality []evmlogger.LogBroadcast
query := `SELECT block_hash, consumed, log_index, job_id FROM log_broadcasts`
- q := pg.NewQ(app.GetSqlxDB(), app.Logger, app.Config.Database())
// Execute the query.
- require.NoError(t, q.Select(&broadcastsBeforeFinality, query))
+ require.NoError(t, app.GetDB().SelectContext(ctx, &broadcastsBeforeFinality, query))
// Ensure there is only one log broadcast (our EOA request), and that
// it hasn't been marked as consumed yet.
@@ -1087,14 +1088,14 @@ func testEoa(
// Ensure the request is still not fulfilled.
gomega.NewGomegaWithT(t).Consistently(func() bool {
uni.backend.Commit()
- runs, err := app.PipelineORM().GetAllRuns()
+ runs, err := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
t.Log("runs", len(runs))
return len(runs) == 0
}, 5*time.Second, time.Second).Should(gomega.BeTrue())
// Execute the query for log broadcasts again after finality depth has elapsed.
- require.NoError(t, q.Select(&broadcastsAfterFinality, query))
+ require.NoError(t, app.GetDB().SelectContext(ctx, &broadcastsAfterFinality, query))
// Ensure that there is still only one log broadcast (our EOA request), but that
// it has been marked as "consumed," such that it won't be retried.
@@ -1158,6 +1159,7 @@ func deployWrapper(t *testing.T, uni coordinatorV2UniverseCommon, wrapperOverhea
func TestVRFV2Integration_SingleConsumer_Wrapper(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
wrapperOverhead := uint32(30_000)
coordinatorOverhead := uint32(90_000)
@@ -1179,7 +1181,7 @@ func TestVRFV2Integration_SingleConsumer_Wrapper(t *testing.T) {
// Fund gas lane.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
jbs := createVRFJobs(
@@ -1221,7 +1223,7 @@ func TestVRFV2Integration_SingleConsumer_Wrapper(t *testing.T) {
// Wait for simulation to pass.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err2 := app.PipelineORM().GetAllRuns()
+ runs, err2 := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err2)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -1238,6 +1240,7 @@ func TestVRFV2Integration_SingleConsumer_Wrapper(t *testing.T) {
func TestVRFV2Integration_Wrapper_High_Gas(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
wrapperOverhead := uint32(30_000)
coordinatorOverhead := uint32(90_000)
@@ -1261,7 +1264,7 @@ func TestVRFV2Integration_Wrapper_High_Gas(t *testing.T) {
// Fund gas lane.
sendEth(t, ownerKey, uni.backend, key1.Address, 10)
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
// Create VRF job.
jbs := createVRFJobs(
@@ -1303,7 +1306,7 @@ func TestVRFV2Integration_Wrapper_High_Gas(t *testing.T) {
// Wait for simulation to pass.
gomega.NewGomegaWithT(t).Eventually(func() bool {
uni.backend.Commit()
- runs, err2 := app.PipelineORM().GetAllRuns()
+ runs, err2 := app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err2)
t.Log("runs", len(runs))
return len(runs) == 1
@@ -1631,6 +1634,7 @@ func TestSimpleConsumerExample(t *testing.T) {
func TestIntegrationVRFV2(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
// Reconfigure the sim chain with a default gas price of 1 gwei,
// max gas limit of 2M and a key specific max 10 gwei price.
// Keep the prices low so we can operate with small link balance subscriptions.
@@ -1650,11 +1654,11 @@ func TestIntegrationVRFV2(t *testing.T) {
carolContractAddress := uni.consumerContractAddresses[0]
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, key)
- keys, err := app.KeyStore.Eth().EnabledKeysForChain(testutils.Context(t), testutils.SimulatedChainID)
+ keys, err := app.KeyStore.Eth().EnabledKeysForChain(ctx, testutils.SimulatedChainID)
require.NoError(t, err)
require.Zero(t, key.Cmp(keys[0]))
- require.NoError(t, app.Start(testutils.Context(t)))
+ require.NoError(t, app.Start(ctx))
var chain legacyevm.Chain
chain, err = app.GetRelayers().LegacyEVMChains().Get(testutils.SimulatedChainID.String())
require.NoError(t, err)
@@ -1723,7 +1727,7 @@ func TestIntegrationVRFV2(t *testing.T) {
// by the node.
var runs []pipeline.Run
gomega.NewWithT(t).Eventually(func() bool {
- runs, err = app.PipelineORM().GetAllRuns()
+ runs, err = app.PipelineORM().GetAllRuns(ctx)
require.NoError(t, err)
// It is possible that we send the test request
// before the job spawner has started the vrf services, which is fine
@@ -1745,7 +1749,7 @@ func TestIntegrationVRFV2(t *testing.T) {
return len(rf) == 1
}, testutils.WaitTimeout(t), 500*time.Millisecond).Should(gomega.BeTrue())
assert.True(t, rf[0].Success(), "expected callback to succeed")
- fulfillReceipt, err := uni.backend.TransactionReceipt(testutils.Context(t), rf[0].Raw().TxHash)
+ fulfillReceipt, err := uni.backend.TransactionReceipt(ctx, rf[0].Raw().TxHash)
require.NoError(t, err)
// Assert all the random words received by the consumer are different and non-zero.
@@ -1813,7 +1817,7 @@ func TestIntegrationVRFV2(t *testing.T) {
// We should see the response count present
require.NoError(t, err)
var counts map[string]uint64
- counts, err = listenerV2.GetStartingResponseCountsV2(testutils.Context(t))
+ counts, err = listenerV2.GetStartingResponseCountsV2(ctx)
require.NoError(t, err)
t.Log(counts, rf[0].RequestID().String())
assert.Equal(t, uint64(1), counts[rf[0].RequestID().String()])
diff --git a/core/services/vrf/v2/listener_v2.go b/core/services/vrf/v2/listener_v2.go
index 71c6e72a06f..e820cff63b7 100644
--- a/core/services/vrf/v2/listener_v2.go
+++ b/core/services/vrf/v2/listener_v2.go
@@ -14,6 +14,7 @@ import (
"github.com/theodesp/go-heaps/pairing"
"github.com/smartcontractkit/chainlink-common/pkg/services"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr"
txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types"
@@ -29,7 +30,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon"
)
@@ -70,7 +70,7 @@ func New(
l logger.Logger,
chain legacyevm.Chain,
chainID *big.Int,
- q pg.Q,
+ ds sqlutil.DataSource,
coordinator CoordinatorV2_X,
batchCoordinator batch_vrf_coordinator_v2.BatchVRFCoordinatorV2Interface,
vrfOwner vrf_owner.VRFOwnerInterface,
@@ -93,7 +93,7 @@ func New(
vrfOwner: vrfOwner,
pipelineRunner: pipelineRunner,
job: job,
- q: q,
+ ds: ds,
gethks: gethks,
chStop: make(chan struct{}),
reqAdded: reqAdded,
@@ -120,7 +120,7 @@ type listenerV2 struct {
pipelineRunner pipeline.Runner
job job.Job
- q pg.Q
+ ds sqlutil.DataSource
gethks keystore.Eth
chStop services.StopChan
diff --git a/core/services/vrf/v2/listener_v2_log_listener.go b/core/services/vrf/v2/listener_v2_log_listener.go
index 6fbe518411d..2d2c08b8590 100644
--- a/core/services/vrf/v2/listener_v2_log_listener.go
+++ b/core/services/vrf/v2/listener_v2_log_listener.go
@@ -129,8 +129,13 @@ func (lsn *listenerV2) initializeLastProcessedBlock(ctx context.Context) (lastPr
}()
numBlocksToReplay := numReplayBlocks(lsn.job.VRFSpec.RequestTimeout, lsn.chain.ID())
- ll.Debugw("running replay on log poller")
- err = lp.Replay(ctx, mathutil.Max(latestBlock.FinalizedBlockNumber-numBlocksToReplay, 1))
+ replayStartBlock := mathutil.Max(latestBlock.FinalizedBlockNumber-numBlocksToReplay, 1)
+ ll.Debugw("running replay on log poller",
+ "numBlocksToReplay", numBlocksToReplay,
+ "replayStartBlock", replayStartBlock,
+ "requestTimeout", lsn.job.VRFSpec.RequestTimeout,
+ )
+ err = lp.Replay(ctx, replayStartBlock)
if err != nil {
return 0, fmt.Errorf("LogPoller.Replay: %w", err)
}
@@ -414,47 +419,56 @@ func (lsn *listenerV2) handleRequested(requested []RandomWordsRequested, request
func numReplayBlocks(requestTimeout time.Duration, chainID *big.Int) int64 {
var timeoutSeconds = int64(requestTimeout.Seconds())
switch chainID.String() {
- case "1": // eth mainnet
- case "3": // eth ropsten
- case "4": // eth rinkeby
- case "5": // eth goerli
- case "11155111": // eth sepolia
+ case
+ "1", // eth mainnet
+ "3", // eth robsten
+ "4", // eth rinkeby
+ "5", // eth goerli
+ "11155111": // eth sepolia
// block time is 12s
return timeoutSeconds / 12
- case "137": // polygon mainnet
- case "80001": // polygon mumbai
+ case
+ "137", // polygon mainnet
+ "80001", // polygon mumbai
+ "80002": // polygon amoy
// block time is 2s
return timeoutSeconds / 2
- case "56": // bsc mainnet
- case "97": // bsc testnet
+ case
+ "56", // bsc mainnet
+ "97": // bsc testnet
// block time is 2s
return timeoutSeconds / 2
- case "43114": // avalanche mainnet
- case "43113": // avalanche fuji
+ case
+ "43114", // avalanche mainnet
+ "43113": // avalanche fuji
// block time is 1s
return timeoutSeconds
- case "250": // fantom mainnet
- case "4002": // fantom testnet
+ case
+ "250", // fantom mainnet
+ "4002": // fantom testnet
// block time is 1s
return timeoutSeconds
- case "42161": // arbitrum mainnet
- case "421613": // arbitrum goerli
- case "421614": // arbitrum sepolia
+ case
+ "42161", // arbitrum mainnet
+ "421613", // arbitrum goerli
+ "421614": // arbitrum sepolia
// block time is 0.25s in the worst case
return timeoutSeconds * 4
- case "10": // optimism mainnet
- case "69": // optimism kovan
- case "420": // optimism goerli
- case "11155420": // optimism sepolia
- case "8453": // base mainnet
- case "84531": // base goerli
- case "84532": // base sepolia
+ case
+ "10", // optimism mainnet
+ "69", // optimism kovan
+ "420", // optimism goerli
+ "11155420": // optimism sepolia
+ // block time is 2s
+ return timeoutSeconds / 2
+ case
+ "8453", // base mainnet
+ "84531", // base goerli
+ "84532": // base sepolia
// block time is 2s
return timeoutSeconds / 2
default:
// assume block time of 1s
return timeoutSeconds
}
- // assume block time of 1s
- return timeoutSeconds
}
diff --git a/core/services/vrf/v2/listener_v2_log_processor.go b/core/services/vrf/v2/listener_v2_log_processor.go
index db84fb47e3e..673f8618c0b 100644
--- a/core/services/vrf/v2/listener_v2_log_processor.go
+++ b/core/services/vrf/v2/listener_v2_log_processor.go
@@ -20,6 +20,7 @@ import (
"github.com/pkg/errors"
"go.uber.org/multierr"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils/hex"
txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr"
txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types"
@@ -28,7 +29,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus_interface"
"github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon"
"github.com/smartcontractkit/chainlink/v2/core/utils"
@@ -565,55 +565,53 @@ func (lsn *listenerV2) enqueueForceFulfillment(
}
// fulfill the request through the VRF owner
- err = lsn.q.Transaction(func(tx pg.Queryer) error {
- lsn.l.Infow("VRFOwner.fulfillRandomWords vs. VRFCoordinatorV2.fulfillRandomWords",
- "vrf_owner.fulfillRandomWords", hexutil.Encode(vrfOwnerABI.Methods["fulfillRandomWords"].ID),
- "vrf_coordinator_v2.fulfillRandomWords", hexutil.Encode(coordinatorV2ABI.Methods["fulfillRandomWords"].ID),
- )
+ lsn.l.Infow("VRFOwner.fulfillRandomWords vs. VRFCoordinatorV2.fulfillRandomWords",
+ "vrf_owner.fulfillRandomWords", hexutil.Encode(vrfOwnerABI.Methods["fulfillRandomWords"].ID),
+ "vrf_coordinator_v2.fulfillRandomWords", hexutil.Encode(coordinatorV2ABI.Methods["fulfillRandomWords"].ID),
+ )
- vrfOwnerAddress1 := lsn.vrfOwner.Address()
- vrfOwnerAddressSpec := lsn.job.VRFSpec.VRFOwnerAddress.Address()
- lsn.l.Infow("addresses diff", "wrapper_address", vrfOwnerAddress1, "spec_address", vrfOwnerAddressSpec)
+ vrfOwnerAddress1 := lsn.vrfOwner.Address()
+ vrfOwnerAddressSpec := lsn.job.VRFSpec.VRFOwnerAddress.Address()
+ lsn.l.Infow("addresses diff", "wrapper_address", vrfOwnerAddress1, "spec_address", vrfOwnerAddressSpec)
- lsn.l.Infow("fulfillRandomWords payload", "proof", p.proof, "commitment", p.reqCommitment.Get(), "payload", p.payload)
- txData := hexutil.MustDecode(p.payload)
- if err != nil {
- return fmt.Errorf("abi pack VRFOwner.fulfillRandomWords: %w", err)
- }
- estimateGasLimit, err := lsn.chain.Client().EstimateGas(ctx, ethereum.CallMsg{
- From: fromAddress,
- To: &vrfOwnerAddressSpec,
- Data: txData,
- })
- if err != nil {
- return fmt.Errorf("failed to estimate gas on VRFOwner.fulfillRandomWords: %w", err)
- }
+ lsn.l.Infow("fulfillRandomWords payload", "proof", p.proof, "commitment", p.reqCommitment.Get(), "payload", p.payload)
+ txData := hexutil.MustDecode(p.payload)
+ if err != nil {
+ err = fmt.Errorf("abi pack VRFOwner.fulfillRandomWords: %w", err)
+ return
+ }
+ estimateGasLimit, err := lsn.chain.Client().EstimateGas(ctx, ethereum.CallMsg{
+ From: fromAddress,
+ To: &vrfOwnerAddressSpec,
+ Data: txData,
+ })
+ if err != nil {
+ err = fmt.Errorf("failed to estimate gas on VRFOwner.fulfillRandomWords: %w", err)
+ return
+ }
- lsn.l.Infow("Estimated gas limit on force fulfillment",
- "estimateGasLimit", estimateGasLimit, "pipelineGasLimit", p.gasLimit)
- if estimateGasLimit < p.gasLimit {
- estimateGasLimit = p.gasLimit
- }
+ lsn.l.Infow("Estimated gas limit on force fulfillment",
+ "estimateGasLimit", estimateGasLimit, "pipelineGasLimit", p.gasLimit)
+ if estimateGasLimit < p.gasLimit {
+ estimateGasLimit = p.gasLimit
+ }
- requestID := common.BytesToHash(p.req.req.RequestID().Bytes())
- subID := p.req.req.SubID()
- requestTxHash := p.req.req.Raw().TxHash
- etx, err = lsn.chain.TxManager().CreateTransaction(ctx, txmgr.TxRequest{
- FromAddress: fromAddress,
- ToAddress: lsn.vrfOwner.Address(),
- EncodedPayload: txData,
- FeeLimit: estimateGasLimit,
- Strategy: txmgrcommon.NewSendEveryStrategy(),
- Meta: &txmgr.TxMeta{
- RequestID: &requestID,
- SubID: ptr(subID.Uint64()),
- RequestTxHash: &requestTxHash,
- // No max link since simulation failed
- },
- })
- return err
+ requestID := common.BytesToHash(p.req.req.RequestID().Bytes())
+ subID := p.req.req.SubID()
+ requestTxHash := p.req.req.Raw().TxHash
+ return lsn.chain.TxManager().CreateTransaction(ctx, txmgr.TxRequest{
+ FromAddress: fromAddress,
+ ToAddress: lsn.vrfOwner.Address(),
+ EncodedPayload: txData,
+ FeeLimit: estimateGasLimit,
+ Strategy: txmgrcommon.NewSendEveryStrategy(),
+ Meta: &txmgr.TxMeta{
+ RequestID: &requestID,
+ SubID: ptr(subID.Uint64()),
+ RequestTxHash: &requestTxHash,
+ // No max link since simulation failed
+ },
})
- return
}
// For an errored pipeline run, wait until the finality depth of the chain to have elapsed,
@@ -786,8 +784,8 @@ func (lsn *listenerV2) processRequestsPerSubHelper(
ll.Infow("Enqueuing fulfillment")
var transaction txmgr.Tx
- err = lsn.q.Transaction(func(tx pg.Queryer) error {
- if err = lsn.pipelineRunner.InsertFinishedRun(p.run, true, pg.WithQueryer(tx)); err != nil {
+ err = sqlutil.TransactDataSource(ctx, lsn.ds, nil, func(tx sqlutil.DataSource) error {
+ if err = lsn.pipelineRunner.InsertFinishedRun(ctx, tx, p.run, true); err != nil {
return err
}
diff --git a/core/services/vrf/v2/listener_v2_types.go b/core/services/vrf/v2/listener_v2_types.go
index f10297f31a9..c7dc45bb3bd 100644
--- a/core/services/vrf/v2/listener_v2_types.go
+++ b/core/services/vrf/v2/listener_v2_types.go
@@ -8,10 +8,10 @@ import (
"github.com/ethereum/go-ethereum/common"
heaps "github.com/theodesp/go-heaps"
+ "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/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon"
)
@@ -222,8 +222,8 @@ func (lsn *listenerV2) processBatch(
)
ll.Info("Enqueuing batch fulfillment")
var ethTX txmgr.Tx
- err = lsn.q.Transaction(func(tx pg.Queryer) error {
- if err = lsn.pipelineRunner.InsertFinishedRuns(batch.runs, true, pg.WithQueryer(tx)); err != nil {
+ err = sqlutil.TransactDataSource(ctx, lsn.ds, nil, func(tx sqlutil.DataSource) error {
+ if err = lsn.pipelineRunner.InsertFinishedRuns(ctx, tx, batch.runs, true); err != nil {
return fmt.Errorf("inserting finished pipeline runs: %w", err)
}
diff --git a/core/services/vrf/v2/reverted_txns.go b/core/services/vrf/v2/reverted_txns.go
index d2f62fbf271..cfd9954a208 100644
--- a/core/services/vrf/v2/reverted_txns.go
+++ b/core/services/vrf/v2/reverted_txns.go
@@ -17,13 +17,13 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/pkg/errors"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -71,15 +71,15 @@ func (lsn *listenerV2) handleRevertedTxns(ctx context.Context, pollPeriod time.D
lsn.l.Infow("Handling reverted txns")
// Fetch recent single and batch txns, that have not been force-fulfilled
- recentSingleTxns, err := lsn.fetchRecentSingleTxns(ctx, lsn.q, lsn.chainID.Uint64(), pollPeriod)
+ recentSingleTxns, err := lsn.fetchRecentSingleTxns(ctx, lsn.ds, lsn.chainID.Uint64(), pollPeriod)
if err != nil {
lsn.l.Fatalw("Fetch recent txns", "err", err)
}
- recentBatchTxns, err := lsn.fetchRecentBatchTxns(ctx, lsn.q, lsn.chainID.Uint64(), pollPeriod)
+ recentBatchTxns, err := lsn.fetchRecentBatchTxns(ctx, lsn.ds, lsn.chainID.Uint64(), pollPeriod)
if err != nil {
lsn.l.Fatalw("Fetch recent batch txns", "err", err)
}
- recentForceFulfillmentTxns, err := lsn.fetchRevertedForceFulfilmentTxns(ctx, lsn.q, lsn.chainID.Uint64(), pollPeriod)
+ recentForceFulfillmentTxns, err := lsn.fetchRevertedForceFulfilmentTxns(ctx, lsn.ds, lsn.chainID.Uint64(), pollPeriod)
if err != nil {
lsn.l.Fatalw("Fetch recent reverted force-fulfillment txns", "err", err)
}
@@ -108,7 +108,7 @@ func (lsn *listenerV2) handleRevertedTxns(ctx context.Context, pollPeriod time.D
}
func (lsn *listenerV2) fetchRecentSingleTxns(ctx context.Context,
- q pg.Q,
+ ds sqlutil.DataSource,
chainID uint64,
pollPeriod time.Duration) ([]TxnReceiptDB, error) {
@@ -155,7 +155,7 @@ func (lsn *listenerV2) fetchRecentSingleTxns(ctx context.Context,
var recentReceipts []TxnReceiptDB
before := time.Now()
- err := q.Select(&recentReceipts, sqlQuery, chainID)
+ err := ds.SelectContext(ctx, &recentReceipts, sqlQuery, chainID)
lsn.postSqlLog(ctx, before, pollPeriod, "FetchRecentSingleTxns")
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, errors.Wrap(err, "Error fetching recent non-force-fulfilled txns")
@@ -172,7 +172,7 @@ func (lsn *listenerV2) fetchRecentSingleTxns(ctx context.Context,
}
func (lsn *listenerV2) fetchRecentBatchTxns(ctx context.Context,
- q pg.Q,
+ ds sqlutil.DataSource,
chainID uint64,
pollPeriod time.Duration) ([]TxnReceiptDB, error) {
sqlQuery := fmt.Sprintf(`
@@ -217,7 +217,7 @@ func (lsn *listenerV2) fetchRecentBatchTxns(ctx context.Context,
var recentReceipts []TxnReceiptDB
before := time.Now()
- err := q.Select(&recentReceipts, sqlQuery, chainID)
+ err := ds.SelectContext(ctx, &recentReceipts, sqlQuery, chainID)
lsn.postSqlLog(ctx, before, pollPeriod, "FetchRecentBatchTxns")
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, errors.Wrap(err, "Error fetching recent non-force-fulfilled txns")
@@ -231,7 +231,7 @@ func (lsn *listenerV2) fetchRecentBatchTxns(ctx context.Context,
}
func (lsn *listenerV2) fetchRevertedForceFulfilmentTxns(ctx context.Context,
- q pg.Q,
+ ds sqlutil.DataSource,
chainID uint64,
pollPeriod time.Duration) ([]TxnReceiptDB, error) {
@@ -271,7 +271,7 @@ func (lsn *listenerV2) fetchRevertedForceFulfilmentTxns(ctx context.Context,
var recentReceipts []TxnReceiptDB
before := time.Now()
- err := q.Select(&recentReceipts, sqlQuery, chainID)
+ err := ds.SelectContext(ctx, &recentReceipts, sqlQuery, chainID)
lsn.postSqlLog(ctx, before, pollPeriod, "FetchRevertedForceFulfilmentTxns")
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, errors.Wrap(err, "Error fetching recent reverted force-fulfilled txns")
@@ -300,7 +300,7 @@ func (lsn *listenerV2) fetchRevertedForceFulfilmentTxns(ctx context.Context,
`, ReqScanTimeRangeInDB)
var allReceipts []TxnReceiptDB
before = time.Now()
- err = q.Select(&allReceipts, sqlQueryAll, chainID)
+ err = ds.SelectContext(ctx, &allReceipts, sqlQueryAll, chainID)
lsn.postSqlLog(ctx, before, pollPeriod, "Fetch all ForceFulfilment Txns")
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, errors.Wrap(err, "Error fetching all recent force-fulfilled txns")
@@ -389,9 +389,10 @@ func (lsn *listenerV2) postSqlLog(ctx context.Context, begin time.Time, pollPeri
lsn.l.Debugw("SQL context canceled", "ms", elapsed.Milliseconds(), "err", ctx.Err(), "sql", queryName)
}
- timeout := lsn.q.QueryTimeout
- if timeout <= 0 {
- timeout = pollPeriod
+ timeout := pollPeriod
+ deadline, ok := ctx.Deadline()
+ if ok {
+ timeout = deadline.Sub(begin)
}
pct := float64(elapsed) / float64(timeout)
diff --git a/core/services/webhook/authorizer_test.go b/core/services/webhook/authorizer_test.go
index 35292c6bbb9..82af7c6fcce 100644
--- a/core/services/webhook/authorizer_test.go
+++ b/core/services/webhook/authorizer_test.go
@@ -3,27 +3,19 @@ package webhook_test
import (
"testing"
- "github.com/jmoiron/sqlx"
-
- "github.com/smartcontractkit/chainlink/v2/core/bridges"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
-
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink/v2/core/bridges"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/services/webhook"
"github.com/smartcontractkit/chainlink/v2/core/sessions"
)
-func newBridgeORM(t *testing.T, db *sqlx.DB, cfg pg.QConfig) bridges.ORM {
- return bridges.NewORM(db, logger.TestLogger(t), cfg)
-}
-
type eiEnabledCfg struct{}
func (eiEnabledCfg) ExternalInitiatorsEnabled() bool { return true }
@@ -34,7 +26,7 @@ func (eiDisabledCfg) ExternalInitiatorsEnabled() bool { return false }
func Test_Authorizer(t *testing.T) {
db := pgtest.NewSqlxDB(t)
- borm := newBridgeORM(t, db, pgtest.NewQConfig(true))
+ borm := bridges.NewORM(db)
eiFoo := cltest.MustInsertExternalInitiator(t, borm)
eiBar := cltest.MustInsertExternalInitiator(t, borm)
diff --git a/core/services/webhook/delegate.go b/core/services/webhook/delegate.go
index 0c08e992f32..690ae38d088 100644
--- a/core/services/webhook/delegate.go
+++ b/core/services/webhook/delegate.go
@@ -13,7 +13,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
)
@@ -74,7 +73,7 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {
)
}
}
-func (d *Delegate) OnDeleteJob(ctx context.Context, jb job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec satisfies the job.Delegate interface.
func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.ServiceCtx, error) {
diff --git a/core/services/webhook/external_initiator_manager_test.go b/core/services/webhook/external_initiator_manager_test.go
index 553455ebe63..22ab50513cf 100644
--- a/core/services/webhook/external_initiator_manager_test.go
+++ b/core/services/webhook/external_initiator_manager_test.go
@@ -13,6 +13,7 @@ import (
"github.com/tidwall/gjson"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
+ "github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
@@ -25,7 +26,7 @@ import (
func Test_ExternalInitiatorManager_Load(t *testing.T) {
db := pgtest.NewSqlxDB(t)
cfg := pgtest.NewQConfig(true)
- borm := newBridgeORM(t, db, cfg)
+ borm := bridges.NewORM(db)
eiFoo := cltest.MustInsertExternalInitiator(t, borm)
eiBar := cltest.MustInsertExternalInitiator(t, borm)
@@ -62,7 +63,7 @@ func Test_ExternalInitiatorManager_Notify(t *testing.T) {
ctx := tests.Context(t)
db := pgtest.NewSqlxDB(t)
cfg := pgtest.NewQConfig(true)
- borm := newBridgeORM(t, db, cfg)
+ borm := bridges.NewORM(db)
eiWithURL := cltest.MustInsertExternalInitiatorWithOpts(t, borm, cltest.ExternalInitiatorOpts{
URL: cltest.MustWebURL(t, "http://example.com/foo"),
@@ -102,7 +103,7 @@ func Test_ExternalInitiatorManager_DeleteJob(t *testing.T) {
ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
cfg := pgtest.NewQConfig(true)
- borm := newBridgeORM(t, db, cfg)
+ borm := bridges.NewORM(db)
eiWithURL := cltest.MustInsertExternalInitiatorWithOpts(t, borm, cltest.ExternalInitiatorOpts{
URL: cltest.MustWebURL(t, "http://example.com/foo"),
diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go
index bde7aa275c4..ed7d266131a 100644
--- a/core/services/workflows/delegate.go
+++ b/core/services/workflows/delegate.go
@@ -3,69 +3,17 @@ package workflows
import (
"context"
"fmt"
- "time"
"github.com/google/uuid"
"github.com/pelletier/go-toml"
- "github.com/smartcontractkit/chainlink-common/pkg/capabilities/mercury"
- "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers"
"github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/targets"
"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
-const hardcodedWorkflow = `
-triggers:
- - type: "mercury-trigger"
- config:
- feedIds:
- - "0x1111111111111111111100000000000000000000000000000000000000000000"
- - "0x2222222222222222222200000000000000000000000000000000000000000000"
- - "0x3333333333333333333300000000000000000000000000000000000000000000"
-
-consensus:
- - type: "offchain_reporting"
- ref: "evm_median"
- inputs:
- observations:
- - "$(trigger.outputs)"
- config:
- aggregation_method: "data_feeds_2_0"
- aggregation_config:
- "0x1111111111111111111100000000000000000000000000000000000000000000":
- deviation: "0.001"
- heartbeat: 3600
- "0x2222222222222222222200000000000000000000000000000000000000000000":
- deviation: "0.001"
- heartbeat: 3600
- "0x3333333333333333333300000000000000000000000000000000000000000000":
- deviation: "0.001"
- heartbeat: 3600
- encoder: "EVM"
- encoder_config:
- abi: "mercury_reports bytes[]"
-
-targets:
- - type: "write_polygon-testnet-mumbai"
- inputs:
- report: "$(evm_median.outputs.report)"
- config:
- address: "0x3F3554832c636721F1fD1822Ccca0354576741Ef"
- params: ["$(report)"]
- abi: "receive(report bytes)"
- - type: "write_ethereum-testnet-sepolia"
- inputs:
- report: "$(evm_median.outputs.report)"
- config:
- address: "0x54e220867af6683aE6DcBF535B4f952cB5116510"
- params: ["$(report)"]
- abi: "receive(report bytes)"
-`
-
type Delegate struct {
registry types.CapabilitiesRegistry
logger logger.Logger
@@ -84,7 +32,7 @@ func (d *Delegate) AfterJobCreated(jb job.Job) {}
func (d *Delegate) BeforeJobDeleted(spec job.Job) {}
-func (d *Delegate) OnDeleteJob(ctx context.Context, jb job.Job, q pg.Queryer) error { return nil }
+func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil }
// ServicesForSpec satisfies the job.Delegate interface.
func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.ServiceCtx, error) {
@@ -94,19 +42,11 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.Ser
d.logger.Errorw("could not initialize writes", err)
}
- trigger := triggers.NewMercuryTriggerService()
- err = d.registry.Add(context.Background(), trigger)
- if err != nil {
- d.logger.Errorw("could not add mercury trigger to registry", err)
- } else {
- go mercuryEventLoop(trigger, d.logger)
- }
-
cfg := Config{
Lggr: d.logger,
- Spec: hardcodedWorkflow,
+ Spec: spec.WorkflowSpec.Workflow,
+ WorkflowID: spec.WorkflowSpec.WorkflowID,
Registry: d.registry,
- WorkflowID: mockedWorkflowID,
}
engine, err := NewEngine(cfg)
if err != nil {
@@ -119,52 +59,6 @@ func NewDelegate(logger logger.Logger, registry types.CapabilitiesRegistry, lega
return &Delegate{logger: logger, registry: registry, legacyEVMChains: legacyEVMChains}
}
-func mercuryEventLoop(trigger *triggers.MercuryTriggerService, logger logger.Logger) {
- sleepSec := 60 * time.Second
- ticker := time.NewTicker(sleepSec)
- defer ticker.Stop()
-
- prices := []int64{300000, 2000, 5000000}
-
- for range ticker.C {
- for i := range prices {
- prices[i] = prices[i] + 1
- }
-
- t := time.Now().Round(sleepSec).Unix()
- reports, err := emitReports(logger, trigger, t, prices)
- if err != nil {
- logger.Errorw("failed to process Mercury reports", "err", err, "timestamp", time.Now().Unix(), "payload", reports)
- }
- }
-}
-
-func emitReports(logger logger.Logger, trigger *triggers.MercuryTriggerService, t int64, prices []int64) ([]triggers.FeedReport, error) {
- reports := []triggers.FeedReport{
- {
- FeedID: mercury.FeedID("0x1111111111111111111100000000000000000000000000000000000000000000").Bytes(),
- FullReport: []byte{},
- BenchmarkPrice: prices[0],
- ObservationTimestamp: t,
- },
- {
- FeedID: mercury.FeedID("0x2222222222222222222200000000000000000000000000000000000000000000").Bytes(),
- FullReport: []byte{},
- BenchmarkPrice: prices[1],
- ObservationTimestamp: t,
- },
- {
- FeedID: mercury.FeedID("0x3333333333333333333300000000000000000000000000000000000000000000").Bytes(),
- FullReport: []byte{},
- BenchmarkPrice: prices[2],
- ObservationTimestamp: t,
- },
- }
-
- logger.Infow("New set of Mercury reports", "timestamp", time.Now().Unix(), "payload", reports)
- return reports, trigger.ProcessReport(reports)
-}
-
func ValidatedWorkflowSpec(tomlString string) (job.Job, error) {
var jb = job.Job{ExternalJobID: uuid.New()}
@@ -178,6 +72,17 @@ func ValidatedWorkflowSpec(tomlString string) (job.Job, error) {
return jb, fmt.Errorf("toml unmarshal error on spec: %w", err)
}
+ var spec job.WorkflowSpec
+ err = tree.Unmarshal(&spec)
+ if err != nil {
+ return jb, fmt.Errorf("toml unmarshal error on job: %w", err)
+ }
+
+ if err := spec.Validate(); err != nil {
+ return jb, err
+ }
+
+ jb.WorkflowSpec = &spec
if jb.Type != job.Workflow {
return jb, fmt.Errorf("unsupported type %s", jb.Type)
}
diff --git a/core/services/workflows/delegate_test.go b/core/services/workflows/delegate_test.go
index fd2df9141bc..68abfa2f7a1 100644
--- a/core/services/workflows/delegate_test.go
+++ b/core/services/workflows/delegate_test.go
@@ -21,6 +21,8 @@ func TestDelegate_JobSpecValidator(t *testing.T) {
`
type = "workflow"
schemaVersion = 1
+workflowId = "15c631d295ef5e32deb99a10ee6804bc4af1385568f9b3363f6552ac6dbb2cef"
+workflowOwner = "00000000000000000000000000000000000000aa"
`,
true,
},
diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go
index f3bb9554095..71d9ab9463e 100644
--- a/core/services/workflows/engine.go
+++ b/core/services/workflows/engine.go
@@ -67,13 +67,13 @@ func (e *Engine) init(ctx context.Context) {
ticker := time.NewTicker(time.Duration(retrySec) * time.Second)
defer ticker.Stop()
- initSuccessful := true
LOOP:
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
+ initSuccessful := true
// Resolve the underlying capability for each trigger
for _, t := range e.workflow.triggers {
tg, err := e.registry.GetTrigger(ctx, t.Type)
@@ -82,9 +82,11 @@ LOOP:
e.logger.Errorf("failed to get trigger capability: %s, retrying in %d seconds", err, retrySec)
continue
}
-
t.trigger = tg
}
+ if !initSuccessful {
+ continue
+ }
// Walk the graph and register each step's capability to this workflow
err := e.workflow.walkDo(keywordTrigger, func(s *step) error {
@@ -181,10 +183,17 @@ func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability) erro
Config: tc,
Inputs: triggerInputs,
}
- err = t.trigger.RegisterTrigger(ctx, e.triggerEvents, triggerRegRequest)
+ eventsCh, err := t.trigger.RegisterTrigger(ctx, triggerRegRequest)
if err != nil {
return fmt.Errorf("failed to instantiate trigger %s, %s", t.Type, err)
}
+
+ go func() {
+ for event := range eventsCh {
+ e.triggerEvents <- event
+ }
+ }()
+
return nil
}
@@ -511,7 +520,15 @@ func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability) er
Inputs: triggerInputs,
Config: t.config,
}
- return t.trigger.UnregisterTrigger(ctx, deregRequest)
+
+ // if t.trigger == nil, then we haven't initialized the workflow
+ // yet, and can safely consider the trigger deregistered with
+ // no further action.
+ if t.trigger != nil {
+ return t.trigger.UnregisterTrigger(ctx, deregRequest)
+ }
+
+ return nil
}
func (e *Engine) Close() error {
@@ -543,6 +560,13 @@ func (e *Engine) Close() error {
Config: s.config,
}
+ // if capability is nil, then we haven't initialized
+ // the workflow yet and can safely consider it deregistered
+ // with no further action.
+ if s.capability == nil {
+ return nil
+ }
+
innerErr := s.capability.UnregisterFromWorkflow(ctx, reg)
if innerErr != nil {
return fmt.Errorf("failed to unregister from workflow: %+v", reg)
diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go
index 57de4cb6faa..7bb6cd00c1c 100644
--- a/core/services/workflows/engine_test.go
+++ b/core/services/workflows/engine_test.go
@@ -16,6 +16,54 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
)
+const hardcodedWorkflow = `
+triggers:
+ - type: "mercury-trigger"
+ config:
+ feedIds:
+ - "0x1111111111111111111100000000000000000000000000000000000000000000"
+ - "0x2222222222222222222200000000000000000000000000000000000000000000"
+ - "0x3333333333333333333300000000000000000000000000000000000000000000"
+
+consensus:
+ - type: "offchain_reporting"
+ ref: "evm_median"
+ inputs:
+ observations:
+ - "$(trigger.outputs)"
+ config:
+ aggregation_method: "data_feeds_2_0"
+ aggregation_config:
+ "0x1111111111111111111100000000000000000000000000000000000000000000":
+ deviation: "0.001"
+ heartbeat: 3600
+ "0x2222222222222222222200000000000000000000000000000000000000000000":
+ deviation: "0.001"
+ heartbeat: 3600
+ "0x3333333333333333333300000000000000000000000000000000000000000000":
+ deviation: "0.001"
+ heartbeat: 3600
+ encoder: "EVM"
+ encoder_config:
+ abi: "mercury_reports bytes[]"
+
+targets:
+ - type: "write_polygon-testnet-mumbai"
+ inputs:
+ report: "$(evm_median.outputs.report)"
+ config:
+ address: "0x3F3554832c636721F1fD1822Ccca0354576741Ef"
+ params: ["$(report)"]
+ abi: "receive(report bytes)"
+ - type: "write_ethereum-testnet-sepolia"
+ inputs:
+ report: "$(evm_median.outputs.report)"
+ config:
+ address: "0x54e220867af6683aE6DcBF535B4f952cB5116510"
+ params: ["$(report)"]
+ abi: "receive(report bytes)"
+`
+
type mockCapability struct {
capabilities.CapabilityInfo
capabilities.CallbackExecutable
@@ -31,16 +79,18 @@ func newMockCapability(info capabilities.CapabilityInfo, transform func(capabili
}
}
-func (m *mockCapability) Execute(ctx context.Context, ch chan<- capabilities.CapabilityResponse, req capabilities.CapabilityRequest) error {
+func (m *mockCapability) Execute(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) {
cr, err := m.transform(req)
if err != nil {
- return err
+ return nil, err
}
+ ch := make(chan capabilities.CapabilityResponse, 10)
+
+ m.response <- cr
ch <- cr
close(ch)
- m.response <- cr
- return nil
+ return ch, nil
}
func (m *mockCapability) RegisterToWorkflow(ctx context.Context, request capabilities.RegisterToWorkflowRequest) error {
@@ -54,13 +104,14 @@ func (m *mockCapability) UnregisterFromWorkflow(ctx context.Context, request cap
type mockTriggerCapability struct {
capabilities.CapabilityInfo
triggerEvent capabilities.CapabilityResponse
+ ch chan capabilities.CapabilityResponse
}
var _ capabilities.TriggerCapability = (*mockTriggerCapability)(nil)
-func (m *mockTriggerCapability) RegisterTrigger(ctx context.Context, ch chan<- capabilities.CapabilityResponse, req capabilities.CapabilityRequest) error {
- ch <- m.triggerEvent
- return nil
+func (m *mockTriggerCapability) RegisterTrigger(ctx context.Context, req capabilities.CapabilityRequest) (<-chan capabilities.CapabilityResponse, error) {
+ m.ch <- m.triggerEvent
+ return m.ch, nil
}
func (m *mockTriggerCapability) UnregisterTrigger(ctx context.Context, req capabilities.CapabilityRequest) error {
@@ -68,6 +119,7 @@ func (m *mockTriggerCapability) UnregisterTrigger(ctx context.Context, req capab
}
func TestEngineWithHardcodedWorkflow(t *testing.T) {
+ t.Parallel()
ctx := testutils.Context(t)
reg := coreCap.NewRegistry(logger.TestLogger(t))
@@ -168,6 +220,7 @@ func mockTrigger(t *testing.T) (capabilities.TriggerCapability, capabilities.Cap
"issues a trigger when a mercury report is received.",
"v1.0.0",
),
+ ch: make(chan capabilities.CapabilityResponse, 10),
}
resp, err := values.NewMap(map[string]any{
"123": decimal.NewFromFloat(1.00),
@@ -240,6 +293,7 @@ func mockTarget() *mockCapability {
}
func TestEngine_ErrorsTheWorkflowIfAStepErrors(t *testing.T) {
+ t.Parallel()
ctx := testutils.Context(t)
reg := coreCap.NewRegistry(logger.TestLogger(t))
@@ -340,6 +394,7 @@ func mockAction() (*mockCapability, values.Value) {
}
func TestEngine_MultiStepDependencies(t *testing.T) {
+ t.Parallel()
ctx := testutils.Context(t)
reg := coreCap.NewRegistry(logger.TestLogger(t))
diff --git a/core/services/workflows/models_test.go b/core/services/workflows/models_test.go
index 61aced2ed19..232e91eaaa8 100644
--- a/core/services/workflows/models_test.go
+++ b/core/services/workflows/models_test.go
@@ -8,6 +8,7 @@ import (
)
func TestParse_Graph(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
yaml string
diff --git a/core/services/workflows/models_yaml_test.go b/core/services/workflows/models_yaml_test.go
index 411781a3782..2732f1b44c7 100644
--- a/core/services/workflows/models_yaml_test.go
+++ b/core/services/workflows/models_yaml_test.go
@@ -52,6 +52,7 @@ var transformJSON = cmp.FilterValues(func(x, y []byte) bool {
}))
func TestWorkflowSpecMarshalling(t *testing.T) {
+ t.Parallel()
fixtureReader := yamlFixtureReaderBytes(t, "marshalling")
t.Run("Type coercion", func(t *testing.T) {
@@ -168,6 +169,7 @@ func TestWorkflowSpecMarshalling(t *testing.T) {
}
func TestJsonSchema(t *testing.T) {
+ t.Parallel()
t.Run("GenerateJsonSchema", func(t *testing.T) {
expectedSchemaPath := fixtureDir + "workflow_schema.json"
generatedSchema, err := GenerateJsonSchema()
diff --git a/core/services/workflows/state_test.go b/core/services/workflows/state_test.go
index 9e69520c242..0917662ccb6 100644
--- a/core/services/workflows/state_test.go
+++ b/core/services/workflows/state_test.go
@@ -11,6 +11,7 @@ import (
)
func TestInterpolateKey(t *testing.T) {
+ t.Parallel()
val, err := values.NewMap(
map[string]any{
"reports": map[string]any{
@@ -202,6 +203,7 @@ func TestInterpolateKey(t *testing.T) {
}
func TestInterpolateInputsFromState(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
inputs map[string]any
diff --git a/core/sessions/authentication.go b/core/sessions/authentication.go
index 0f0dda3bf33..b923d5c16c7 100644
--- a/core/sessions/authentication.go
+++ b/core/sessions/authentication.go
@@ -1,6 +1,7 @@
package sessions
import (
+ "context"
"errors"
"fmt"
@@ -33,9 +34,9 @@ var ErrEmptySessionID = errors.New("session ID cannot be empty")
// as local admin management (ie initial core node setup, initial admin user creation), is always
// required no matter what the pluggable AuthenticationProvider implementation is.
type BasicAdminUsersORM interface {
- ListUsers() ([]User, error)
- CreateUser(user *User) error
- FindUser(email string) (User, error)
+ ListUsers(ctx context.Context) ([]User, error)
+ CreateUser(ctx context.Context, user *User) error
+ FindUser(ctx context.Context, email string) (User, error)
}
//go:generate mockery --quiet --name AuthenticationProvider --output ./mocks/ --case=underscore
@@ -43,24 +44,24 @@ type BasicAdminUsersORM interface {
// AuthenticationProvider is an interface that abstracts the required application calls to a user management backend
// Currently localauth (users table DB) or LDAP server (readonly)
type AuthenticationProvider interface {
- FindUser(email string) (User, error)
- FindUserByAPIToken(apiToken string) (User, error)
- ListUsers() ([]User, error)
- AuthorizedUserWithSession(sessionID string) (User, error)
- DeleteUser(email string) error
- DeleteUserSession(sessionID string) error
- CreateSession(sr SessionRequest) (string, error)
- ClearNonCurrentSessions(sessionID string) error
- CreateUser(user *User) error
- UpdateRole(email, newRole string) (User, error)
- SetAuthToken(user *User, token *auth.Token) error
- CreateAndSetAuthToken(user *User) (*auth.Token, error)
- DeleteAuthToken(user *User) error
- SetPassword(user *User, newPassword string) error
- TestPassword(email, password string) error
- Sessions(offset, limit int) ([]Session, error)
- GetUserWebAuthn(email string) ([]WebAuthn, error)
- SaveWebAuthn(token *WebAuthn) error
+ FindUser(ctx context.Context, email string) (User, error)
+ FindUserByAPIToken(ctx context.Context, apiToken string) (User, error)
+ ListUsers(ctx context.Context) ([]User, error)
+ AuthorizedUserWithSession(ctx context.Context, sessionID string) (User, error)
+ DeleteUser(ctx context.Context, email string) error
+ DeleteUserSession(ctx context.Context, sessionID string) error
+ CreateSession(ctx context.Context, sr SessionRequest) (string, error)
+ ClearNonCurrentSessions(ctx context.Context, sessionID string) error
+ CreateUser(ctx context.Context, user *User) error
+ UpdateRole(ctx context.Context, email, newRole string) (User, error)
+ SetAuthToken(ctx context.Context, user *User, token *auth.Token) error
+ CreateAndSetAuthToken(ctx context.Context, user *User) (*auth.Token, error)
+ DeleteAuthToken(ctx context.Context, user *User) error
+ SetPassword(ctx context.Context, user *User, newPassword string) error
+ TestPassword(ctx context.Context, email, password string) error
+ Sessions(ctx context.Context, offset, limit int) ([]Session, error)
+ GetUserWebAuthn(ctx context.Context, email string) ([]WebAuthn, error)
+ SaveWebAuthn(ctx context.Context, token *WebAuthn) error
- FindExternalInitiator(eia *auth.Token) (initiator *bridges.ExternalInitiator, err error)
+ FindExternalInitiator(ctx context.Context, eia *auth.Token) (initiator *bridges.ExternalInitiator, err error)
}
diff --git a/core/sessions/ldapauth/helpers_test.go b/core/sessions/ldapauth/helpers_test.go
index 5c19afd17d3..1bb4abf6341 100644
--- a/core/sessions/ldapauth/helpers_test.go
+++ b/core/sessions/ldapauth/helpers_test.go
@@ -3,27 +3,22 @@ package ldapauth
import (
"time"
- "github.com/jmoiron/sqlx"
-
commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/logger/audit"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
// Returns an instantiated ldapAuthenticator struct without validation for testing
func NewTestLDAPAuthenticator(
- db *sqlx.DB,
- pgCfg pg.QConfig,
+ ds sqlutil.DataSource,
ldapCfg config.LDAP,
- dev bool,
lggr logger.Logger,
auditLogger audit.AuditLogger,
) (*ldapAuthenticator, error) {
- namedLogger := lggr.Named("LDAPAuthenticationProvider")
ldapAuth := ldapAuthenticator{
- q: pg.NewQ(db, namedLogger, pgCfg),
+ ds: ds,
ldapClient: newLDAPClient(ldapCfg),
config: ldapCfg,
lggr: lggr.Named("LDAPAuthenticationProvider"),
diff --git a/core/sessions/ldapauth/ldap.go b/core/sessions/ldapauth/ldap.go
index fc0e76bb5c1..efbedcd8d11 100644
--- a/core/sessions/ldapauth/ldap.go
+++ b/core/sessions/ldapauth/ldap.go
@@ -24,6 +24,7 @@ for a blocking auth call while the user responds to a potential push notificatio
package ldapauth
import (
+ "context"
"crypto/subtle"
"database/sql"
"errors"
@@ -32,15 +33,14 @@ import (
"time"
"github.com/go-ldap/ldap/v3"
- "github.com/jmoiron/sqlx"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mathutil"
"github.com/smartcontractkit/chainlink/v2/core/auth"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/logger/audit"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/sessions"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -53,7 +53,7 @@ var ErrUserNotInUpstream = errors.New("LDAP query returned no matching users")
var ErrUserNoLDAPGroups = errors.New("user present in directory, but matching no role groups assigned")
type ldapAuthenticator struct {
- q pg.Q
+ ds sqlutil.DataSource
ldapClient LDAPClient
config config.LDAP
lggr logger.Logger
@@ -64,15 +64,12 @@ type ldapAuthenticator struct {
var _ sessions.AuthenticationProvider = (*ldapAuthenticator)(nil)
func NewLDAPAuthenticator(
- db *sqlx.DB,
- pgCfg pg.QConfig,
+ ds sqlutil.DataSource,
ldapCfg config.LDAP,
dev bool,
lggr logger.Logger,
auditLogger audit.AuditLogger,
) (*ldapAuthenticator, error) {
- namedLogger := lggr.Named("LDAPAuthenticationProvider")
-
// If not chainlink dev and not tls, error
if !dev && !ldapCfg.ServerTLS() {
return nil, errors.New("LDAP Authentication driver requires TLS when running in Production mode")
@@ -91,7 +88,7 @@ func NewLDAPAuthenticator(
}
ldapAuth := ldapAuthenticator{
- q: pg.NewQ(db, namedLogger, pgCfg),
+ ds: ds,
ldapClient: newLDAPClient(ldapCfg),
config: ldapCfg,
lggr: lggr.Named("LDAPAuthenticationProvider"),
@@ -114,16 +111,12 @@ func NewLDAPAuthenticator(
}
// FindUser will attempt to return an LDAP user with mapped role by email.
-func (l *ldapAuthenticator) FindUser(email string) (sessions.User, error) {
+func (l *ldapAuthenticator) FindUser(ctx context.Context, email string) (sessions.User, error) {
email = strings.ToLower(email)
- foundUser := sessions.User{}
// First check for the supported local admin users table
var foundLocalAdminUser sessions.User
- checkErr := l.q.Transaction(func(tx pg.Queryer) error {
- sql := "SELECT * FROM users WHERE lower(email) = lower($1)"
- return tx.Get(&foundLocalAdminUser, sql, email)
- })
+ checkErr := l.ds.GetContext(ctx, &foundLocalAdminUser, "SELECT * FROM users WHERE lower(email) = lower($1)", email)
if checkErr == nil {
return foundLocalAdminUser, nil
}
@@ -138,19 +131,19 @@ func (l *ldapAuthenticator) FindUser(email string) (sessions.User, error) {
usersActive, err := l.validateUsersActive([]string{email})
if err != nil {
if errors.Is(err, ErrUserNotInUpstream) {
- return foundUser, ErrUserNotInUpstream
+ return sessions.User{}, ErrUserNotInUpstream
}
l.lggr.Errorf("error in validateUsers call: %v", err)
- return foundUser, errors.New("error running query to validate user active")
+ return sessions.User{}, errors.New("error running query to validate user active")
}
if !usersActive[0] {
- return foundUser, errors.New("user not active")
+ return sessions.User{}, errors.New("user not active")
}
conn, err := l.ldapClient.CreateEphemeralConnection()
if err != nil {
l.lggr.Errorf("error in LDAP dial: ", err)
- return foundUser, errors.New("unable to establish connection to LDAP server with provided URL and credentials")
+ return sessions.User{}, errors.New("unable to establish connection to LDAP server with provided URL and credentials")
}
defer conn.Close()
@@ -173,30 +166,24 @@ func (l *ldapAuthenticator) FindUser(email string) (sessions.User, error) {
result, err := conn.Search(searchRequest)
if err != nil {
l.lggr.Errorf("error searching users in LDAP query: %v", err)
- return foundUser, errors.New("error searching users in LDAP directory")
+ return sessions.User{}, errors.New("error searching users in LDAP directory")
}
if len(result.Entries) == 0 {
// Provided email is not present in upstream LDAP server, local admin CLI auth is supported
// So query and check the users table as well before failing
- if err = l.q.Transaction(func(tx pg.Queryer) error {
- var localUserRole sessions.UserRole
- if err = tx.Get(&localUserRole, "SELECT role FROM users WHERE email = $1", email); err != nil {
- return err
- }
- foundUser = sessions.User{
- Email: email,
- Role: localUserRole,
- }
- return nil
- }); err != nil {
+ var localUserRole sessions.UserRole
+ if err = l.ds.GetContext(ctx, &localUserRole, "SELECT role FROM users WHERE email = $1", email); err != nil {
// Above query for local user unsuccessful, return error
l.lggr.Warnf("No local users table user found with email %s", email)
- return foundUser, errors.New("no users found with provided email")
+ return sessions.User{}, errors.New("no users found with provided email")
}
// If the above query to the local users table was successful, return that local user's role
- return foundUser, nil
+ return sessions.User{
+ Email: email,
+ Role: localUserRole,
+ }, nil
}
// Populate found user by email and role based on matched group names
@@ -207,59 +194,48 @@ func (l *ldapAuthenticator) FindUser(email string) (sessions.User, error) {
}
// Convert search result to sessions.User type with required fields
- foundUser = sessions.User{
+ return sessions.User{
Email: email,
Role: userRole,
- }
-
- return foundUser, nil
+ }, nil
}
// FindUserByAPIToken retrieves a possible stored user and role from the ldap_user_api_tokens table store
-func (l *ldapAuthenticator) FindUserByAPIToken(apiToken string) (sessions.User, error) {
+func (l *ldapAuthenticator) FindUserByAPIToken(ctx context.Context, apiToken string) (sessions.User, error) {
if !l.config.UserApiTokenEnabled() {
return sessions.User{}, errors.New("API token is not enabled ")
}
- var foundUser sessions.User
- err := l.q.Transaction(func(tx pg.Queryer) error {
- // Query the ldap user API token table for given token, user role and email are cached so
- // no further upstream LDAP query is performed, sessions and tokens are synced against the upstream server
- // via the UpstreamSyncInterval config and reaper.go sync implementation
- var foundUserToken struct {
- UserEmail string
- UserRole sessions.UserRole
- Valid bool
- }
- if err := tx.Get(&foundUserToken,
- "SELECT user_email, user_role, created_at + $2 >= now() as valid FROM ldap_user_api_tokens WHERE token_key = $1",
- apiToken, l.config.UserAPITokenDuration().Duration(),
- ); err != nil {
- return err
- }
- if !foundUserToken.Valid {
- return sessions.ErrUserSessionExpired
- }
- foundUser = sessions.User{
- Email: foundUserToken.UserEmail,
- Role: foundUserToken.UserRole,
- }
- return nil
- })
+ // Query the ldap user API token table for given token, user role and email are cached so
+ // no further upstream LDAP query is performed, sessions and tokens are synced against the upstream server
+ // via the UpstreamSyncInterval config and reaper.go sync implementation
+ var foundUserToken struct {
+ UserEmail string
+ UserRole sessions.UserRole
+ Valid bool
+ }
+ err := l.ds.GetContext(ctx, &foundUserToken,
+ "SELECT user_email, user_role, created_at + $2 >= now() as valid FROM ldap_user_api_tokens WHERE token_key = $1",
+ apiToken, l.config.UserAPITokenDuration().Duration(),
+ )
if err != nil {
- if errors.Is(err, sessions.ErrUserSessionExpired) {
- // API Token expired, purge
- if _, execErr := l.q.Exec("DELETE FROM ldap_user_api_tokens WHERE token_key = $1", apiToken); err != nil {
- l.lggr.Errorf("error purging stale ldap API token session: %v", execErr)
- }
- }
return sessions.User{}, err
}
- return foundUser, nil
+ if !foundUserToken.Valid { // API Token expired, purge
+ if _, execErr := l.ds.ExecContext(ctx, "DELETE FROM ldap_user_api_tokens WHERE token_key = $1", apiToken); execErr != nil {
+ l.lggr.Errorf("error purging stale ldap API token session: %v", execErr)
+ }
+ return sessions.User{}, sessions.ErrUserSessionExpired
+ }
+
+ return sessions.User{
+ Email: foundUserToken.UserEmail,
+ Role: foundUserToken.UserRole,
+ }, nil
}
// ListUsers will load and return all active users in applicable LDAP groups, extended with local admin users as well
-func (l *ldapAuthenticator) ListUsers() ([]sessions.User, error) {
+func (l *ldapAuthenticator) ListUsers(ctx context.Context) ([]sessions.User, error) {
// For each defined role/group, query for the list of group members to gather the full list of possible users
users := []sessions.User{}
var err error
@@ -338,10 +314,8 @@ func (l *ldapAuthenticator) ListUsers() ([]sessions.User, error) {
// Extend with local admin users
var localAdminUsers []sessions.User
- if err := l.q.Transaction(func(tx pg.Queryer) error {
- sql := "SELECT * FROM users ORDER BY email ASC;"
- return tx.Select(&localAdminUsers, sql)
- }); err != nil {
+ sql := "SELECT * FROM users ORDER BY email ASC;"
+ if err := l.ds.SelectContext(ctx, &localAdminUsers, sql); err != nil {
l.lggr.Errorf("error extending upstream LDAP users with local admin users in users table: ", err)
} else {
returnUsers = append(returnUsers, localAdminUsers...)
@@ -367,60 +341,50 @@ func (l *ldapAuthenticator) ldapGroupMembersListToUser(conn LDAPConn, groupNameC
// AuthorizedUserWithSession will return the API user associated with the Session ID if it
// exists and hasn't expired, and update session's LastUsed field. The state of the upstream LDAP server
// is polled and synced at the defined interval via a SleeperTask
-func (l *ldapAuthenticator) AuthorizedUserWithSession(sessionID string) (sessions.User, error) {
+func (l *ldapAuthenticator) AuthorizedUserWithSession(ctx context.Context, sessionID string) (sessions.User, error) {
if len(sessionID) == 0 {
return sessions.User{}, errors.New("session ID cannot be empty")
}
- var foundUser sessions.User
- err := l.q.Transaction(func(tx pg.Queryer) error {
- // Query the ldap_sessions table for given session ID, user role and email are cached so
- // no further upstream LDAP query is performed
- var foundSession struct {
- UserEmail string
- UserRole sessions.UserRole
- Valid bool
- }
- if err := tx.Get(&foundSession,
- "SELECT user_email, user_role, created_at + $2 >= now() as valid FROM ldap_sessions WHERE id = $1",
- sessionID, l.config.SessionTimeout().Duration(),
- ); err != nil {
- return sessions.ErrUserSessionExpired
- }
- if !foundSession.Valid {
- // Sessions expired, purge
- return sessions.ErrUserSessionExpired
- }
- foundUser = sessions.User{
- Email: foundSession.UserEmail,
- Role: foundSession.UserRole,
+ // Query the ldap_sessions table for given session ID, user role and email are cached so
+ // no further upstream LDAP query is performed
+ var foundSession struct {
+ UserEmail string
+ UserRole sessions.UserRole
+ Valid bool
+ }
+ if err := l.ds.GetContext(ctx, &foundSession,
+ "SELECT user_email, user_role, created_at + $2 >= now() as valid FROM ldap_sessions WHERE id = $1",
+ sessionID, l.config.SessionTimeout().Duration(),
+ ); err != nil {
+ return sessions.User{}, sessions.ErrUserSessionExpired
+ }
+ if !foundSession.Valid {
+ // Sessions expired, purge
+ if _, execErr := l.ds.ExecContext(ctx, "DELETE FROM ldap_sessions WHERE id = $1", sessionID); execErr != nil {
+ l.lggr.Errorf("error purging stale ldap session: %v", execErr)
}
- return nil
- })
- if err != nil {
- if errors.Is(err, sessions.ErrUserSessionExpired) {
- if _, execErr := l.q.Exec("DELETE FROM ldap_sessions WHERE id = $1", sessionID); err != nil {
- l.lggr.Errorf("error purging stale ldap session: %v", execErr)
- }
- }
- return sessions.User{}, err
+ return sessions.User{}, sessions.ErrUserSessionExpired
}
- return foundUser, nil
+ return sessions.User{
+ Email: foundSession.UserEmail,
+ Role: foundSession.UserRole,
+ }, nil
}
// DeleteUser is not supported for read only LDAP
-func (l *ldapAuthenticator) DeleteUser(email string) error {
+func (l *ldapAuthenticator) DeleteUser(ctx context.Context, email string) error {
return sessions.ErrNotSupported
}
// DeleteUserSession removes an ldapSession table entry by ID
-func (l *ldapAuthenticator) DeleteUserSession(sessionID string) error {
- _, err := l.q.Exec("DELETE FROM ldap_sessions WHERE id = $1", sessionID)
+func (l *ldapAuthenticator) DeleteUserSession(ctx context.Context, sessionID string) error {
+ _, err := l.ds.ExecContext(ctx, "DELETE FROM ldap_sessions WHERE id = $1", sessionID)
return err
}
// GetUserWebAuthn returns an empty stub, MFA token prompt is handled either by the upstream
// server blocking callback, or an error code to pass a OTP
-func (l *ldapAuthenticator) GetUserWebAuthn(email string) ([]sessions.WebAuthn, error) {
+func (l *ldapAuthenticator) GetUserWebAuthn(ctx context.Context, email string) ([]sessions.WebAuthn, error) {
return []sessions.WebAuthn{}, nil
}
@@ -428,7 +392,7 @@ func (l *ldapAuthenticator) GetUserWebAuthn(email string) ([]sessions.WebAuthn,
// LDAP server, querying for a user + role response if username and
// password match. The API call is blocking with timeout, so a sufficient timeout
// should allow the user to respond to potential MFA push notifications
-func (l *ldapAuthenticator) CreateSession(sr sessions.SessionRequest) (string, error) {
+func (l *ldapAuthenticator) CreateSession(ctx context.Context, sr sessions.SessionRequest) (string, error) {
conn, err := l.ldapClient.CreateEphemeralConnection()
if err != nil {
return "", errors.New("unable to establish connection to LDAP server with provided URL and credentials")
@@ -448,7 +412,7 @@ func (l *ldapAuthenticator) CreateSession(sr sessions.SessionRequest) (string, e
// Bind was successful meaning user and credentials are present in LDAP directory
// Reuse FindUser functionality to fetch user roles used to create ldap_session entry
// with cached user email and role
- foundUser, err := l.FindUser(escapedEmail)
+ foundUser, err := l.FindUser(ctx, escapedEmail)
if err != nil {
l.lggr.Infof("Successful user login, but error querying for user groups: user: %s, error %v", escapedEmail, err)
returnErr = errors.New("log in successful, but no assigned groups to assume role")
@@ -458,7 +422,7 @@ func (l *ldapAuthenticator) CreateSession(sr sessions.SessionRequest) (string, e
if returnErr != nil {
// Unable to log in against LDAP server, attempt fallback local auth with credentials, case of local CLI Admin account
// Successful local user sessions can not be managed by the upstream server and have expiration handled by the reaper sync module
- foundUser, returnErr = l.localLoginFallback(sr)
+ foundUser, returnErr = l.localLoginFallback(ctx, sr)
isLocalUser = true
}
@@ -473,7 +437,8 @@ func (l *ldapAuthenticator) CreateSession(sr sessions.SessionRequest) (string, e
// Sessions are set to expire after the duration + creation date elapsed, and are synced on an interval against the upstream
// LDAP server
session := sessions.NewSession()
- _, err = l.q.Exec(
+ _, err = l.ds.ExecContext(
+ ctx,
"INSERT INTO ldap_sessions (id, user_email, user_role, localauth_user, created_at) VALUES ($1, $2, $3, $4, now())",
session.ID,
strings.ToLower(sr.Email),
@@ -491,30 +456,28 @@ func (l *ldapAuthenticator) CreateSession(sr sessions.SessionRequest) (string, e
}
// ClearNonCurrentSessions removes all ldap_sessions but the id passed in.
-func (l *ldapAuthenticator) ClearNonCurrentSessions(sessionID string) error {
- _, err := l.q.Exec("DELETE FROM ldap_sessions where id != $1", sessionID)
+func (l *ldapAuthenticator) ClearNonCurrentSessions(ctx context.Context, sessionID string) error {
+ _, err := l.ds.ExecContext(ctx, "DELETE FROM ldap_sessions where id != $1", sessionID)
return err
}
// CreateUser is not supported for read only LDAP
-func (l *ldapAuthenticator) CreateUser(user *sessions.User) error {
+func (l *ldapAuthenticator) CreateUser(ctx context.Context, user *sessions.User) error {
return sessions.ErrNotSupported
}
// UpdateRole is not supported for read only LDAP
-func (l *ldapAuthenticator) UpdateRole(email, newRole string) (sessions.User, error) {
+func (l *ldapAuthenticator) UpdateRole(ctx context.Context, email, newRole string) (sessions.User, error) {
return sessions.User{}, sessions.ErrNotSupported
}
// SetPassword for remote users is not supported via the read only LDAP implementation, however change password
// in the context of updating a local admin user's password is required
-func (l *ldapAuthenticator) SetPassword(user *sessions.User, newPassword string) error {
+func (l *ldapAuthenticator) SetPassword(ctx context.Context, user *sessions.User, newPassword string) error {
// Ensure specified user is part of the local admins user table
var localAdminUser sessions.User
- if err := l.q.Transaction(func(tx pg.Queryer) error {
- sql := "SELECT * FROM users WHERE lower(email) = lower($1)"
- return tx.Get(&localAdminUser, sql, user.Email)
- }); err != nil {
+ sql := "SELECT * FROM users WHERE lower(email) = lower($1)"
+ if err := l.ds.GetContext(ctx, &localAdminUser, sql, user.Email); err != nil {
l.lggr.Infof("Can not change password, local user with email not found in users table: %s, err: %v", user.Email, err)
return sessions.ErrNotSupported
}
@@ -524,10 +487,8 @@ func (l *ldapAuthenticator) SetPassword(user *sessions.User, newPassword string)
if err != nil {
return err
}
- if err := l.q.Transaction(func(tx pg.Queryer) error {
- sql := "UPDATE users SET hashed_password = $1, updated_at = now() WHERE email = $2 RETURNING *"
- return tx.Get(user, sql, hashedPassword, user.Email)
- }); err != nil {
+ sql = "UPDATE users SET hashed_password = $1, updated_at = now() WHERE email = $2 RETURNING *"
+ if err := l.ds.GetContext(ctx, user, sql, hashedPassword, user.Email); err != nil {
l.lggr.Errorf("unable to set password for user: %s, err: %v", user.Email, err)
return errors.New("unable to save password")
}
@@ -535,7 +496,7 @@ func (l *ldapAuthenticator) SetPassword(user *sessions.User, newPassword string)
}
// TestPassword tests if an LDAP login bind can be performed with provided credentials, returns nil if success
-func (l *ldapAuthenticator) TestPassword(email string, password string) error {
+func (l *ldapAuthenticator) TestPassword(ctx context.Context, email string, password string) error {
conn, err := l.ldapClient.CreateEphemeralConnection()
if err != nil {
return errors.New("unable to establish connection to LDAP server with provided URL and credentials")
@@ -553,7 +514,7 @@ func (l *ldapAuthenticator) TestPassword(email string, password string) error {
// Fall back to test local users table in case of supported local CLI users as well
var hashedPassword string
- if err := l.q.Get(&hashedPassword, "SELECT hashed_password FROM users WHERE lower(email) = lower($1)", email); err != nil {
+ if err := l.ds.GetContext(ctx, &hashedPassword, "SELECT hashed_password FROM users WHERE lower(email) = lower($1)", email); err != nil {
return errors.New("invalid credentials")
}
if !utils.CheckPasswordHash(password, hashedPassword) {
@@ -564,10 +525,10 @@ func (l *ldapAuthenticator) TestPassword(email string, password string) error {
}
// CreateAndSetAuthToken generates a new credential token with the user role
-func (l *ldapAuthenticator) CreateAndSetAuthToken(user *sessions.User) (*auth.Token, error) {
+func (l *ldapAuthenticator) CreateAndSetAuthToken(ctx context.Context, user *sessions.User) (*auth.Token, error) {
newToken := auth.NewToken()
- err := l.SetAuthToken(user, newToken)
+ err := l.SetAuthToken(ctx, user, newToken)
if err != nil {
return nil, err
}
@@ -576,7 +537,7 @@ func (l *ldapAuthenticator) CreateAndSetAuthToken(user *sessions.User) (*auth.To
}
// SetAuthToken updates the user to use the given Authentication Token.
-func (l *ldapAuthenticator) SetAuthToken(user *sessions.User, token *auth.Token) error {
+func (l *ldapAuthenticator) SetAuthToken(ctx context.Context, user *sessions.User, token *auth.Token) error {
if !l.config.UserApiTokenEnabled() {
return errors.New("API token is not enabled ")
}
@@ -587,22 +548,23 @@ func (l *ldapAuthenticator) SetAuthToken(user *sessions.User, token *auth.Token)
return fmt.Errorf("LDAPAuth SetAuthToken hashed secret error: %w", err)
}
- err = l.q.Transaction(func(tx pg.Queryer) error {
+ err = sqlutil.TransactDataSource(ctx, l.ds, nil, func(tx sqlutil.DataSource) error {
// Is this user a local CLI Admin or upstream LDAP user?
// Check presence in local users table. Set localauth_user column true if present.
// This flag omits the session/token from being purged by the sync daemon/reaper.go
isLocalCLIAdmin := false
- err = l.q.QueryRow("SELECT EXISTS (SELECT 1 FROM users WHERE email = $1)", user.Email).Scan(&isLocalCLIAdmin)
+ err = l.ds.QueryRowxContext(ctx, "SELECT EXISTS (SELECT 1 FROM users WHERE email = $1)", user.Email).Scan(&isLocalCLIAdmin)
if err != nil {
return fmt.Errorf("error checking user presence in users table: %w", err)
}
// Remove any existing API tokens
- if _, err = l.q.Exec("DELETE FROM ldap_user_api_tokens WHERE user_email = $1", user.Email); err != nil {
+ if _, err = l.ds.ExecContext(ctx, "DELETE FROM ldap_user_api_tokens WHERE user_email = $1", user.Email); err != nil {
return fmt.Errorf("error executing DELETE FROM ldap_user_api_tokens: %w", err)
}
// Create new API token for user
- _, err = l.q.Exec(
+ _, err = l.ds.ExecContext(
+ ctx,
"INSERT INTO ldap_user_api_tokens (user_email, user_role, localauth_user, token_key, token_salt, token_hashed_secret, created_at) VALUES ($1, $2, $3, $4, $5, $6, now())",
user.Email,
user.Role,
@@ -625,39 +587,39 @@ func (l *ldapAuthenticator) SetAuthToken(user *sessions.User, token *auth.Token)
}
// DeleteAuthToken clears and disables the users Authentication Token.
-func (l *ldapAuthenticator) DeleteAuthToken(user *sessions.User) error {
- _, err := l.q.Exec("DELETE FROM ldap_user_api_tokens WHERE email = $1")
+func (l *ldapAuthenticator) DeleteAuthToken(ctx context.Context, user *sessions.User) error {
+ _, err := l.ds.ExecContext(ctx, "DELETE FROM ldap_user_api_tokens WHERE email = $1")
return err
}
// SaveWebAuthn is not supported for read only LDAP
-func (l *ldapAuthenticator) SaveWebAuthn(token *sessions.WebAuthn) error {
+func (l *ldapAuthenticator) SaveWebAuthn(ctx context.Context, token *sessions.WebAuthn) error {
return sessions.ErrNotSupported
}
// Sessions returns all sessions limited by the parameters.
-func (l *ldapAuthenticator) Sessions(offset, limit int) ([]sessions.Session, error) {
+func (l *ldapAuthenticator) Sessions(ctx context.Context, offset, limit int) ([]sessions.Session, error) {
var sessions []sessions.Session
sql := `SELECT * FROM ldap_sessions ORDER BY created_at, id LIMIT $1 OFFSET $2;`
- if err := l.q.Select(&sessions, sql, limit, offset); err != nil {
+ if err := l.ds.SelectContext(ctx, &sessions, sql, limit, offset); err != nil {
return sessions, nil
}
return sessions, nil
}
// FindExternalInitiator supports the 'Run' role external intiator header auth functionality
-func (l *ldapAuthenticator) FindExternalInitiator(eia *auth.Token) (*bridges.ExternalInitiator, error) {
+func (l *ldapAuthenticator) FindExternalInitiator(ctx context.Context, eia *auth.Token) (*bridges.ExternalInitiator, error) {
exi := &bridges.ExternalInitiator{}
- err := l.q.Get(exi, `SELECT * FROM external_initiators WHERE access_key = $1`, eia.AccessKey)
+ err := l.ds.GetContext(ctx, exi, `SELECT * FROM external_initiators WHERE access_key = $1`, eia.AccessKey)
return exi, err
}
// localLoginFallback tests the credentials provided against the 'local' authentication method
// This covers the case of local CLI API calls requiring local login separate from the LDAP server
-func (l *ldapAuthenticator) localLoginFallback(sr sessions.SessionRequest) (sessions.User, error) {
+func (l *ldapAuthenticator) localLoginFallback(ctx context.Context, sr sessions.SessionRequest) (sessions.User, error) {
var user sessions.User
sql := "SELECT * FROM users WHERE lower(email) = lower($1)"
- err := l.q.Get(&user, sql, sr.Email)
+ err := l.ds.GetContext(ctx, &user, sql, sr.Email)
if err != nil {
return user, err
}
diff --git a/core/sessions/ldapauth/ldap_test.go b/core/sessions/ldapauth/ldap_test.go
index c85e0db831e..ff3bc4096dc 100644
--- a/core/sessions/ldapauth/ldap_test.go
+++ b/core/sessions/ldapauth/ldap_test.go
@@ -14,6 +14,7 @@ import (
"github.com/jmoiron/sqlx"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/logger/audit"
@@ -28,7 +29,7 @@ func setupAuthenticationProvider(t *testing.T, ldapClient ldapauth.LDAPClient) (
cfg := ldapauth.TestConfig{}
db := pgtest.NewSqlxDB(t)
- ldapAuthProvider, err := ldapauth.NewTestLDAPAuthenticator(db, pgtest.NewQConfig(true), &cfg, true, logger.TestLogger(t), &audit.AuditLoggerService{})
+ ldapAuthProvider, err := ldapauth.NewTestLDAPAuthenticator(db, &cfg, logger.TestLogger(t), &audit.AuditLoggerService{})
if err != nil {
t.Fatalf("Error constructing NewTestLDAPAuthenticator: %v\n", err)
}
@@ -40,6 +41,7 @@ func setupAuthenticationProvider(t *testing.T, ldapClient ldapauth.LDAPClient) (
func TestORM_FindUser_Empty(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
mockLdapClient := mocks.NewLDAPClient(t)
mockLdapConnProvider := mocks.NewLDAPConn(t)
@@ -56,12 +58,13 @@ func TestORM_FindUser_Empty(t *testing.T) {
mockLdapConnProvider.On("Search", mock.AnythingOfType("*ldap.SearchRequest")).Return(&expectedResults, nil)
// Not in upstream, no local admin users, expect error
- _, err := ldapAuthProvider.FindUser("unknown-user")
+ _, err := ldapAuthProvider.FindUser(ctx, "unknown-user")
require.ErrorContains(t, err, "LDAP query returned no matching users")
}
func TestORM_FindUser_NoGroups(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
mockLdapClient := mocks.NewLDAPClient(t)
mockLdapConnProvider := mocks.NewLDAPConn(t)
@@ -95,12 +98,13 @@ func TestORM_FindUser_NoGroups(t *testing.T) {
mockLdapConnProvider.On("Search", mock.AnythingOfType("*ldap.SearchRequest")).Return(&expectedResults, nil)
// No Groups, expect error
- _, err := ldapAuthProvider.FindUser(user1.Email)
+ _, err := ldapAuthProvider.FindUser(ctx, user1.Email)
require.ErrorContains(t, err, "user present in directory, but matching no role groups assigned")
}
func TestORM_FindUser_NotActive(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
mockLdapClient := mocks.NewLDAPClient(t)
mockLdapConnProvider := mocks.NewLDAPConn(t)
@@ -134,12 +138,13 @@ func TestORM_FindUser_NotActive(t *testing.T) {
mockLdapConnProvider.On("Search", mock.AnythingOfType("*ldap.SearchRequest")).Return(&expectedResults, nil)
// User not active, expect error
- _, err := ldapAuthProvider.FindUser(user1.Email)
+ _, err := ldapAuthProvider.FindUser(ctx, user1.Email)
require.ErrorContains(t, err, "user not active")
}
func TestORM_FindUser_Single(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
mockLdapClient := mocks.NewLDAPClient(t)
mockLdapConnProvider := mocks.NewLDAPConn(t)
@@ -189,7 +194,7 @@ func TestORM_FindUser_Single(t *testing.T) {
mockLdapConnProvider.On("Search", mock.AnythingOfType("*ldap.SearchRequest")).Return(&expectedGroupResults, nil).Once()
// User active, and has editor group. Expect success
- user, err := ldapAuthProvider.FindUser(user1.Email)
+ user, err := ldapAuthProvider.FindUser(ctx, user1.Email)
require.NoError(t, err)
require.Equal(t, user1.Email, user.Email)
require.Equal(t, sessions.UserRoleEdit, user.Role)
@@ -197,19 +202,21 @@ func TestORM_FindUser_Single(t *testing.T) {
func TestORM_FindUser_FallbackMatchLocalAdmin(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
// Initilaize LDAP Authentication Provider with mock client
mockLdapClient := mocks.NewLDAPClient(t)
_, ldapAuthProvider := setupAuthenticationProvider(t, mockLdapClient)
// Not in upstream, but utilize text fixture admin user presence in test DB. Succeed
- user, err := ldapAuthProvider.FindUser(cltest.APIEmailAdmin)
+ user, err := ldapAuthProvider.FindUser(ctx, cltest.APIEmailAdmin)
require.NoError(t, err)
require.Equal(t, cltest.APIEmailAdmin, user.Email)
require.Equal(t, sessions.UserRoleAdmin, user.Role)
}
func TestORM_FindUserByAPIToken_Success(t *testing.T) {
+ ctx := testutils.Context(t)
// Initilaize LDAP Authentication Provider with mock client
mockLdapClient := mocks.NewLDAPClient(t)
db, ldapAuthProvider := setupAuthenticationProvider(t, mockLdapClient)
@@ -221,13 +228,14 @@ func TestORM_FindUserByAPIToken_Success(t *testing.T) {
require.NoError(t, err)
// Found user by API token in specific ldap_user_api_tokens table
- user, err := ldapAuthProvider.FindUserByAPIToken(apiToken)
+ user, err := ldapAuthProvider.FindUserByAPIToken(ctx, apiToken)
require.NoError(t, err)
require.Equal(t, testEmail, user.Email)
require.Equal(t, sessions.UserRoleEdit, user.Role)
}
func TestORM_FindUserByAPIToken_Expired(t *testing.T) {
+ ctx := testutils.Context(t)
cfg := ldapauth.TestConfig{}
// Initilaize LDAP Authentication Provider with mock client
@@ -242,12 +250,13 @@ func TestORM_FindUserByAPIToken_Expired(t *testing.T) {
require.NoError(t, err)
// Token found, but expired. Expect error
- _, err = ldapAuthProvider.FindUserByAPIToken(apiToken)
+ _, err = ldapAuthProvider.FindUserByAPIToken(ctx, apiToken)
require.Equal(t, sessions.ErrUserSessionExpired, err)
}
func TestORM_ListUsers_Full(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
mockLdapClient := mocks.NewLDAPClient(t)
mockLdapConnProvider := mocks.NewLDAPConn(t)
@@ -365,7 +374,7 @@ func TestORM_ListUsers_Full(t *testing.T) {
// Asserts 'uid=' parsing log in ldapGroupMembersListToUser
// Expected full list of users above, including local admin user, excluding 'inactive' and duplicate users
- users, err := ldapAuthProvider.ListUsers()
+ users, err := ldapAuthProvider.ListUsers(ctx)
require.NoError(t, err)
require.Equal(t, users[0].Email, user1.Email)
require.Equal(t, users[0].Role, sessions.UserRoleAdmin)
@@ -381,6 +390,7 @@ func TestORM_ListUsers_Full(t *testing.T) {
func TestORM_CreateSession_UpstreamBind(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
mockLdapClient := mocks.NewLDAPClient(t)
mockLdapConnProvider := mocks.NewLDAPConn(t)
@@ -436,12 +446,13 @@ func TestORM_CreateSession_UpstreamBind(t *testing.T) {
Password: cltest.Password,
}
- _, err := ldapAuthProvider.CreateSession(sessionRequest)
+ _, err := ldapAuthProvider.CreateSession(ctx, sessionRequest)
require.NoError(t, err)
}
func TestORM_CreateSession_LocalAdminFallbackLogin(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
mockLdapClient := mocks.NewLDAPClient(t)
mockLdapConnProvider := mocks.NewLDAPConn(t)
@@ -461,7 +472,7 @@ func TestORM_CreateSession_LocalAdminFallbackLogin(t *testing.T) {
Password: cltest.Password,
}
- _, err := ldapAuthProvider.CreateSession(sessionRequest)
+ _, err := ldapAuthProvider.CreateSession(ctx, sessionRequest)
require.NoError(t, err)
// Finally, assert login failing altogether
@@ -472,12 +483,13 @@ func TestORM_CreateSession_LocalAdminFallbackLogin(t *testing.T) {
Password: "incorrect-password",
}
- _, err = ldapAuthProvider.CreateSession(sessionRequest)
+ _, err = ldapAuthProvider.CreateSession(ctx, sessionRequest)
require.ErrorContains(t, err, "invalid password")
}
func TestORM_SetPassword_LocalAdminFallbackLogin(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
mockLdapClient := mocks.NewLDAPClient(t)
mockLdapConnProvider := mocks.NewLDAPConn(t)
@@ -497,7 +509,7 @@ func TestORM_SetPassword_LocalAdminFallbackLogin(t *testing.T) {
Password: cltest.Password,
}
- _, err := ldapAuthProvider.CreateSession(sessionRequest)
+ _, err := ldapAuthProvider.CreateSession(ctx, sessionRequest)
require.NoError(t, err)
// Finally, assert login failing altogether
@@ -508,7 +520,7 @@ func TestORM_SetPassword_LocalAdminFallbackLogin(t *testing.T) {
Password: "incorrect-password",
}
- _, err = ldapAuthProvider.CreateSession(sessionRequest)
+ _, err = ldapAuthProvider.CreateSession(ctx, sessionRequest)
require.ErrorContains(t, err, "invalid password")
}
diff --git a/core/sessions/localauth/orm.go b/core/sessions/localauth/orm.go
index 8afaf5e7fc1..de0688b9ff1 100644
--- a/core/sessions/localauth/orm.go
+++ b/core/sessions/localauth/orm.go
@@ -1,26 +1,26 @@
package localauth
import (
+ "context"
"crypto/subtle"
"encoding/json"
"strings"
"time"
- "github.com/jmoiron/sqlx"
pkgerrors "github.com/pkg/errors"
+ "github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
"github.com/smartcontractkit/chainlink-common/pkg/utils/mathutil"
"github.com/smartcontractkit/chainlink/v2/core/auth"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/logger/audit"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/sessions"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
type orm struct {
- q pg.Q
+ ds sqlutil.DataSource
sessionDuration time.Duration
lggr logger.Logger
auditLogger audit.AuditLogger
@@ -30,10 +30,9 @@ type orm struct {
var _ sessions.AuthenticationProvider = (*orm)(nil)
var _ sessions.BasicAdminUsersORM = (*orm)(nil)
-func NewORM(db *sqlx.DB, sd time.Duration, lggr logger.Logger, cfg pg.QConfig, auditLogger audit.AuditLogger) sessions.AuthenticationProvider {
- namedLogger := lggr.Named("LocalAuthAuthenticationProviderORM")
+func NewORM(ds sqlutil.DataSource, sd time.Duration, lggr logger.Logger, auditLogger audit.AuditLogger) sessions.AuthenticationProvider {
return &orm{
- q: pg.NewQ(db, namedLogger, cfg),
+ ds: ds,
sessionDuration: sd,
lggr: lggr.Named("LocalAuthAuthenticationProviderORM"),
auditLogger: auditLogger,
@@ -41,33 +40,33 @@ func NewORM(db *sqlx.DB, sd time.Duration, lggr logger.Logger, cfg pg.QConfig, a
}
// FindUser will attempt to return an API user by email.
-func (o *orm) FindUser(email string) (sessions.User, error) {
- return o.findUser(email)
+func (o *orm) FindUser(ctx context.Context, email string) (sessions.User, error) {
+ return o.findUser(ctx, email)
}
// FindUserByAPIToken will attempt to return an API user via the user's table token_key column.
-func (o *orm) FindUserByAPIToken(apiToken string) (user sessions.User, err error) {
+func (o *orm) FindUserByAPIToken(ctx context.Context, apiToken string) (user sessions.User, err error) {
sql := "SELECT * FROM users WHERE token_key = $1"
- err = o.q.Get(&user, sql, apiToken)
+ err = o.ds.GetContext(ctx, &user, sql, apiToken)
return
}
-func (o *orm) findUser(email string) (user sessions.User, err error) {
+func (o *orm) findUser(ctx context.Context, email string) (user sessions.User, err error) {
sql := "SELECT * FROM users WHERE lower(email) = lower($1)"
- err = o.q.Get(&user, sql, email)
+ err = o.ds.GetContext(ctx, &user, sql, email)
return
}
// ListUsers will load and return all user rows from the db.
-func (o *orm) ListUsers() (users []sessions.User, err error) {
+func (o *orm) ListUsers(ctx context.Context) (users []sessions.User, err error) {
sql := "SELECT * FROM users ORDER BY email ASC;"
- err = o.q.Select(&users, sql)
+ err = o.ds.SelectContext(ctx, &users, sql)
return
}
// findValidSession finds an unexpired session by its ID and returns the associated email.
-func (o *orm) findValidSession(sessionID string) (email string, err error) {
- if err := o.q.Get(&email, "SELECT email FROM sessions WHERE id = $1 AND last_used + $2 >= now() FOR UPDATE", sessionID, o.sessionDuration); err != nil {
+func (o *orm) findValidSession(ctx context.Context, sessionID string) (email string, err error) {
+ if err := o.ds.GetContext(ctx, &email, "SELECT email FROM sessions WHERE id = $1 AND last_used + $2 >= now() FOR UPDATE", sessionID, o.sessionDuration); err != nil {
o.lggr.Infof("query result: %v", email)
return email, pkgerrors.Wrap(err, "no matching user for provided session token")
}
@@ -75,30 +74,31 @@ func (o *orm) findValidSession(sessionID string) (email string, err error) {
}
// updateSessionLastUsed updates a session by its ID and sets the LastUsed field to now().
-func (o *orm) updateSessionLastUsed(sessionID string) error {
- return o.q.ExecQ("UPDATE sessions SET last_used = now() WHERE id = $1", sessionID)
+func (o *orm) updateSessionLastUsed(ctx context.Context, sessionID string) error {
+ _, err := o.ds.ExecContext(ctx, "UPDATE sessions SET last_used = now() WHERE id = $1", sessionID)
+ return err
}
// AuthorizedUserWithSession will return the API user associated with the Session ID if it
// exists and hasn't expired, and update session's LastUsed field.
// AuthorizedUserWithSession will return the API user associated with the Session ID if it
// exists and hasn't expired, and update session's LastUsed field.
-func (o *orm) AuthorizedUserWithSession(sessionID string) (user sessions.User, err error) {
+func (o *orm) AuthorizedUserWithSession(ctx context.Context, sessionID string) (user sessions.User, err error) {
if len(sessionID) == 0 {
return sessions.User{}, sessions.ErrEmptySessionID
}
- email, err := o.findValidSession(sessionID)
+ email, err := o.findValidSession(ctx, sessionID)
if err != nil {
return sessions.User{}, sessions.ErrUserSessionExpired
}
- user, err = o.findUser(email)
+ user, err = o.findUser(ctx, email)
if err != nil {
return sessions.User{}, sessions.ErrUserSessionExpired
}
- if err := o.updateSessionLastUsed(sessionID); err != nil {
+ if err := o.updateSessionLastUsed(ctx, sessionID); err != nil {
return sessions.User{}, err
}
@@ -106,10 +106,10 @@ func (o *orm) AuthorizedUserWithSession(sessionID string) (user sessions.User, e
}
// DeleteUser will delete an API User and sessions by email.
-func (o *orm) DeleteUser(email string) error {
- return o.q.Transaction(func(tx pg.Queryer) error {
+func (o *orm) DeleteUser(ctx context.Context, email string) error {
+ return sqlutil.TransactDataSource(ctx, o.ds, nil, func(tx sqlutil.DataSource) error {
// session table rows are deleted on cascade through the user email constraint
- if _, err := tx.Exec("DELETE FROM users WHERE email = $1", email); err != nil {
+ if _, err := tx.ExecContext(ctx, "DELETE FROM users WHERE email = $1", email); err != nil {
return err
}
return nil
@@ -117,8 +117,8 @@ func (o *orm) DeleteUser(email string) error {
}
// DeleteUserSession will delete a session by ID.
-func (o *orm) DeleteUserSession(sessionID string) error {
- _, err := o.q.Exec("DELETE FROM sessions WHERE id = $1", sessionID)
+func (o *orm) DeleteUserSession(ctx context.Context, sessionID string) error {
+ _, err := o.ds.ExecContext(ctx, "DELETE FROM sessions WHERE id = $1", sessionID)
return err
}
@@ -126,9 +126,9 @@ func (o *orm) DeleteUserSession(sessionID string) error {
// tokens for the user. This list must be used when logging in (for obvious reasons) but
// must also be used for registration to prevent the user from enrolling the same hardware
// token multiple times.
-func (o *orm) GetUserWebAuthn(email string) ([]sessions.WebAuthn, error) {
+func (o *orm) GetUserWebAuthn(ctx context.Context, email string) ([]sessions.WebAuthn, error) {
var uwas []sessions.WebAuthn
- err := o.q.Select(&uwas, "SELECT email, public_key_data FROM web_authns WHERE LOWER(email) = $1", strings.ToLower(email))
+ err := o.ds.SelectContext(ctx, &uwas, "SELECT email, public_key_data FROM web_authns WHERE LOWER(email) = $1", strings.ToLower(email))
if err != nil {
return uwas, err
}
@@ -140,8 +140,8 @@ func (o *orm) GetUserWebAuthn(email string) ([]sessions.WebAuthn, error) {
// CreateSession will check the password in the SessionRequest against
// the hashed API User password in the db. Also will check WebAuthn if it's
// enabled for that user.
-func (o *orm) CreateSession(sr sessions.SessionRequest) (string, error) {
- user, err := o.FindUser(sr.Email)
+func (o *orm) CreateSession(ctx context.Context, sr sessions.SessionRequest) (string, error) {
+ user, err := o.FindUser(ctx, sr.Email)
if err != nil {
return "", err
}
@@ -161,7 +161,7 @@ func (o *orm) CreateSession(sr sessions.SessionRequest) (string, error) {
}
// Load all valid MFA tokens associated with user's email
- uwas, err := o.GetUserWebAuthn(user.Email)
+ uwas, err := o.GetUserWebAuthn(ctx, user.Email)
if err != nil {
// There was an error with the database query
lggr.Errorf("Could not fetch user's MFA data: %v", err)
@@ -172,7 +172,7 @@ func (o *orm) CreateSession(sr sessions.SessionRequest) (string, error) {
if len(uwas) == 0 {
lggr.Infof("No MFA for user. Creating Session")
session := sessions.NewSession()
- _, err = o.q.Exec("INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, user.Email)
+ _, err = o.ds.ExecContext(ctx, "INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, user.Email)
o.auditLogger.Audit(audit.AuthLoginSuccessNo2FA, map[string]interface{}{"email": sr.Email})
return session.ID, err
}
@@ -212,7 +212,7 @@ func (o *orm) CreateSession(sr sessions.SessionRequest) (string, error) {
lggr.Infof("User passed MFA authentication and login will proceed")
// This is a success so we can create the sessions
session := sessions.NewSession()
- _, err = o.q.Exec("INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, user.Email)
+ _, err = o.ds.ExecContext(ctx, "INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, user.Email)
if err != nil {
return "", err
}
@@ -240,28 +240,28 @@ func constantTimeEmailCompare(left, right string) bool {
}
// ClearNonCurrentSessions removes all sessions but the id passed in.
-func (o *orm) ClearNonCurrentSessions(sessionID string) error {
- _, err := o.q.Exec("DELETE FROM sessions where id != $1", sessionID)
+func (o *orm) ClearNonCurrentSessions(ctx context.Context, sessionID string) error {
+ _, err := o.ds.ExecContext(ctx, "DELETE FROM sessions where id != $1", sessionID)
return err
}
// CreateUser creates a new API user
-func (o *orm) CreateUser(user *sessions.User) error {
+func (o *orm) CreateUser(ctx context.Context, user *sessions.User) error {
sql := "INSERT INTO users (email, hashed_password, role, created_at, updated_at) VALUES ($1, $2, $3, now(), now()) RETURNING *"
- return o.q.Get(user, sql, strings.ToLower(user.Email), user.HashedPassword, user.Role)
+ return o.ds.GetContext(ctx, user, sql, strings.ToLower(user.Email), user.HashedPassword, user.Role)
}
// UpdateRole overwrites role field of the user specified by email.
-func (o *orm) UpdateRole(email, newRole string) (sessions.User, error) {
+func (o *orm) UpdateRole(ctx context.Context, email, newRole string) (sessions.User, error) {
var userToEdit sessions.User
if newRole == "" {
return userToEdit, pkgerrors.New("user role must be specified")
}
- err := o.q.Transaction(func(tx pg.Queryer) error {
+ err := sqlutil.TransactDataSource(ctx, o.ds, nil, func(tx sqlutil.DataSource) error {
// First, attempt to load specified user by email
- if err := tx.Get(&userToEdit, "SELECT * FROM users WHERE lower(email) = lower($1)", email); err != nil {
+ if err := tx.GetContext(ctx, &userToEdit, "SELECT * FROM users WHERE lower(email) = lower($1)", email); err != nil {
return pkgerrors.New("no matching user for provided email")
}
@@ -272,14 +272,14 @@ func (o *orm) UpdateRole(email, newRole string) (sessions.User, error) {
}
userToEdit.Role = userRole
- _, err = tx.Exec("DELETE FROM sessions WHERE email = lower($1)", email)
+ _, err = tx.ExecContext(ctx, "DELETE FROM sessions WHERE email = lower($1)", email)
if err != nil {
o.lggr.Errorf("Failed to purge user sessions for UpdateRole", "err", err)
return pkgerrors.New("error updating API user")
}
sql := "UPDATE users SET role = $1, updated_at = now() WHERE lower(email) = lower($2) RETURNING *"
- if err := tx.Get(&userToEdit, sql, userToEdit.Role, email); err != nil {
+ if err := tx.GetContext(ctx, &userToEdit, sql, userToEdit.Role, email); err != nil {
o.lggr.Errorf("Error updating API user", "err", err)
return pkgerrors.New("error updating API user")
}
@@ -291,19 +291,19 @@ func (o *orm) UpdateRole(email, newRole string) (sessions.User, error) {
}
// SetAuthToken updates the user to use the given Authentication Token.
-func (o *orm) SetPassword(user *sessions.User, newPassword string) error {
+func (o *orm) SetPassword(ctx context.Context, user *sessions.User, newPassword string) error {
hashedPassword, err := utils.HashPassword(newPassword)
if err != nil {
return err
}
sql := "UPDATE users SET hashed_password = $1, updated_at = now() WHERE email = $2 RETURNING *"
- return o.q.Get(user, sql, hashedPassword, user.Email)
+ return o.ds.GetContext(ctx, user, sql, hashedPassword, user.Email)
}
// TestPassword checks plaintext user provided password with hashed database password, returns nil if matched
-func (o *orm) TestPassword(email string, password string) error {
+func (o *orm) TestPassword(ctx context.Context, email string, password string) error {
var hashedPassword string
- if err := o.q.Get(&hashedPassword, "SELECT hashed_password FROM users WHERE lower(email) = lower($1)", email); err != nil {
+ if err := o.ds.GetContext(ctx, &hashedPassword, "SELECT hashed_password FROM users WHERE lower(email) = lower($1)", email); err != nil {
return pkgerrors.New("no matching user for provided email")
}
if !utils.CheckPasswordHash(password, hashedPassword) {
@@ -312,10 +312,10 @@ func (o *orm) TestPassword(email string, password string) error {
return nil
}
-func (o *orm) CreateAndSetAuthToken(user *sessions.User) (*auth.Token, error) {
+func (o *orm) CreateAndSetAuthToken(ctx context.Context, user *sessions.User) (*auth.Token, error) {
newToken := auth.NewToken()
- err := o.SetAuthToken(user, newToken)
+ err := o.SetAuthToken(ctx, user, newToken)
if err != nil {
return nil, err
}
@@ -324,33 +324,33 @@ func (o *orm) CreateAndSetAuthToken(user *sessions.User) (*auth.Token, error) {
}
// SetAuthToken updates the user to use the given Authentication Token.
-func (o *orm) SetAuthToken(user *sessions.User, token *auth.Token) error {
+func (o *orm) SetAuthToken(ctx context.Context, user *sessions.User, token *auth.Token) error {
salt := utils.NewSecret(utils.DefaultSecretSize)
hashedSecret, err := auth.HashedSecret(token, salt)
if err != nil {
return pkgerrors.Wrap(err, "user")
}
sql := "UPDATE users SET token_salt = $1, token_key = $2, token_hashed_secret = $3, updated_at = now() WHERE email = $4 RETURNING *"
- return o.q.Get(user, sql, salt, token.AccessKey, hashedSecret, user.Email)
+ return o.ds.GetContext(ctx, user, sql, salt, token.AccessKey, hashedSecret, user.Email)
}
// DeleteAuthToken clears and disables the users Authentication Token.
-func (o *orm) DeleteAuthToken(user *sessions.User) error {
+func (o *orm) DeleteAuthToken(ctx context.Context, user *sessions.User) error {
sql := "UPDATE users SET token_salt = '', token_key = '', token_hashed_secret = '', updated_at = now() WHERE email = $1 RETURNING *"
- return o.q.Get(user, sql, user.Email)
+ return o.ds.GetContext(ctx, user, sql, user.Email)
}
// SaveWebAuthn saves new WebAuthn token information.
-func (o *orm) SaveWebAuthn(token *sessions.WebAuthn) error {
+func (o *orm) SaveWebAuthn(ctx context.Context, token *sessions.WebAuthn) error {
sql := "INSERT INTO web_authns (email, public_key_data) VALUES ($1, $2)"
- _, err := o.q.Exec(sql, token.Email, token.PublicKeyData)
+ _, err := o.ds.ExecContext(ctx, sql, token.Email, token.PublicKeyData)
return err
}
// Sessions returns all sessions limited by the parameters.
-func (o *orm) Sessions(offset, limit int) (sessions []sessions.Session, err error) {
+func (o *orm) Sessions(ctx context.Context, offset, limit int) (sessions []sessions.Session, err error) {
sql := `SELECT * FROM sessions ORDER BY created_at, id LIMIT $1 OFFSET $2;`
- if err = o.q.Select(&sessions, sql, limit, offset); err != nil {
+ if err = o.ds.SelectContext(ctx, &sessions, sql, limit, offset); err != nil {
return
}
return
@@ -358,9 +358,10 @@ func (o *orm) Sessions(offset, limit int) (sessions []sessions.Session, err erro
// NOTE: this is duplicated from the bridges ORM to appease the AuthStorer interface
func (o *orm) FindExternalInitiator(
+ ctx context.Context,
eia *auth.Token,
) (*bridges.ExternalInitiator, error) {
exi := &bridges.ExternalInitiator{}
- err := o.q.Get(exi, `SELECT * FROM external_initiators WHERE access_key = $1`, eia.AccessKey)
+ err := o.ds.GetContext(ctx, exi, `SELECT * FROM external_initiators WHERE access_key = $1`, eia.AccessKey)
return exi, err
}
diff --git a/core/sessions/localauth/orm_test.go b/core/sessions/localauth/orm_test.go
index c2e155de282..1087af9499c 100644
--- a/core/sessions/localauth/orm_test.go
+++ b/core/sessions/localauth/orm_test.go
@@ -15,6 +15,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/auth"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/logger/audit"
@@ -27,24 +28,25 @@ func setupORM(t *testing.T) (*sqlx.DB, sessions.AuthenticationProvider) {
t.Helper()
db := pgtest.NewSqlxDB(t)
- orm := localauth.NewORM(db, time.Minute, logger.TestLogger(t), pgtest.NewQConfig(true), &audit.AuditLoggerService{})
+ orm := localauth.NewORM(db, time.Minute, logger.TestLogger(t), &audit.AuditLoggerService{})
return db, orm
}
func TestORM_FindUser(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, orm := setupORM(t)
user1 := cltest.MustRandomUser(t)
user2 := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&user1))
- require.NoError(t, orm.CreateUser(&user2))
+ require.NoError(t, orm.CreateUser(ctx, &user1))
+ require.NoError(t, orm.CreateUser(ctx, &user2))
_, err := db.Exec("UPDATE users SET created_at = now() - interval '1 day' WHERE email = $1", user2.Email)
require.NoError(t, err)
- actual, err := orm.FindUser(user1.Email)
+ actual, err := orm.FindUser(ctx, user1.Email)
require.NoError(t, err)
assert.Equal(t, user1.Email, actual.Email)
assert.Equal(t, user1.HashedPassword, actual.HashedPassword)
@@ -67,11 +69,12 @@ func TestORM_AuthorizedUserWithSession(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
- orm := localauth.NewORM(db, test.sessionDuration, logger.TestLogger(t), pgtest.NewQConfig(true), &audit.AuditLoggerService{})
+ orm := localauth.NewORM(db, test.sessionDuration, logger.TestLogger(t), &audit.AuditLoggerService{})
user := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&user))
+ require.NoError(t, orm.CreateUser(ctx, &user))
prevSession := cltest.NewSession("correctID")
prevSession.LastUsed = time.Now().Add(-cltest.MustParseDuration(t, "2m"))
@@ -79,7 +82,7 @@ func TestORM_AuthorizedUserWithSession(t *testing.T) {
require.NoError(t, err)
expectedTime := utils.ISO8601UTC(time.Now())
- actual, err := orm.AuthorizedUserWithSession(test.sessionID)
+ actual, err := orm.AuthorizedUserWithSession(ctx, test.sessionID)
if test.wantError != "" {
require.EqualError(t, err, test.wantError)
} else {
@@ -96,58 +99,61 @@ func TestORM_AuthorizedUserWithSession(t *testing.T) {
func TestORM_DeleteUser(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
_, orm := setupORM(t)
u := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&u))
+ require.NoError(t, orm.CreateUser(ctx, &u))
- err := orm.DeleteUser(u.Email)
+ err := orm.DeleteUser(ctx, u.Email)
require.NoError(t, err)
- _, err = orm.FindUser(u.Email)
+ _, err = orm.FindUser(ctx, u.Email)
require.Error(t, err)
}
func TestORM_DeleteUserSession(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
db, orm := setupORM(t)
u := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&u))
+ require.NoError(t, orm.CreateUser(ctx, &u))
session := sessions.NewSession()
_, err := db.Exec("INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, u.Email)
require.NoError(t, err)
- err = orm.DeleteUserSession(session.ID)
+ err = orm.DeleteUserSession(ctx, session.ID)
require.NoError(t, err)
- _, err = orm.FindUser(u.Email)
+ _, err = orm.FindUser(ctx, u.Email)
require.NoError(t, err)
- sessions, err := orm.Sessions(0, 10)
+ sessions, err := orm.Sessions(ctx, 0, 10)
assert.NoError(t, err)
require.Empty(t, sessions)
}
func TestORM_DeleteUserCascade(t *testing.T) {
+ ctx := testutils.Context(t)
db, orm := setupORM(t)
u := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&u))
+ require.NoError(t, orm.CreateUser(ctx, &u))
session := sessions.NewSession()
_, err := db.Exec("INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, u.Email)
require.NoError(t, err)
- err = orm.DeleteUser(u.Email)
+ err = orm.DeleteUser(ctx, u.Email)
require.NoError(t, err)
- _, err = orm.FindUser(u.Email)
+ _, err = orm.FindUser(ctx, u.Email)
require.Error(t, err)
- sessions, err := orm.Sessions(0, 10)
+ sessions, err := orm.Sessions(ctx, 0, 10)
assert.NoError(t, err)
require.Empty(t, sessions)
}
@@ -158,7 +164,7 @@ func TestORM_CreateSession(t *testing.T) {
_, orm := setupORM(t)
initial := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&initial))
+ require.NoError(t, orm.CreateUser(testutils.Context(t), &initial))
tests := []struct {
name string
@@ -179,7 +185,7 @@ func TestORM_CreateSession(t *testing.T) {
Password: test.password,
}
- sessionID, err := orm.CreateSession(sessionRequest)
+ sessionID, err := orm.CreateSession(testutils.Context(t), sessionRequest)
if test.wantSession {
require.NoError(t, err)
assert.NotEmpty(t, sessionID)
@@ -193,13 +199,14 @@ func TestORM_CreateSession(t *testing.T) {
func TestORM_WebAuthn(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
_, orm := setupORM(t)
initial := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&initial))
+ require.NoError(t, orm.CreateUser(ctx, &initial))
- was, err := orm.GetUserWebAuthn(initial.Email)
+ was, err := orm.GetUserWebAuthn(ctx, initial.Email)
require.NoError(t, err)
assert.Len(t, was, 0)
@@ -208,13 +215,13 @@ func TestORM_WebAuthn(t *testing.T) {
PublicKey: []byte("test-key"),
AttestationType: "test-attestation",
}
- require.NoError(t, sessions.AddCredentialToUser(orm, initial.Email, &cred))
+ require.NoError(t, sessions.AddCredentialToUser(ctx, orm, initial.Email, &cred))
- was, err = orm.GetUserWebAuthn(initial.Email)
+ was, err = orm.GetUserWebAuthn(ctx, initial.Email)
require.NoError(t, err)
require.NotEmpty(t, was)
- _, err = orm.CreateSession(sessions.SessionRequest{
+ _, err = orm.CreateSession(ctx, sessions.SessionRequest{
Email: initial.Email,
Password: cltest.Password,
})
@@ -222,7 +229,7 @@ func TestORM_WebAuthn(t *testing.T) {
require.ErrorContains(t, err, "MFA Error")
ss := sessions.NewWebAuthnSessionStore()
- _, err = orm.CreateSession(sessions.SessionRequest{
+ _, err = orm.CreateSession(ctx, sessions.SessionRequest{
Email: initial.Email,
Password: cltest.Password,
WebAuthnConfig: sessions.WebAuthnConfiguration{
@@ -236,7 +243,7 @@ func TestORM_WebAuthn(t *testing.T) {
require.NoError(t, json.Unmarshal([]byte(err.Error()), &ca))
require.Equal(t, "test-rpid", ca.Response.RelyingPartyID)
- _, err = orm.CreateSession(sessions.SessionRequest{
+ _, err = orm.CreateSession(ctx, sessions.SessionRequest{
Email: initial.Email,
Password: cltest.Password,
WebAuthnConfig: sessions.WebAuthnConfiguration{
@@ -258,7 +265,7 @@ func TestORM_WebAuthn(t *testing.T) {
},
})
require.NoError(t, err)
- _, err = orm.CreateSession(sessions.SessionRequest{
+ _, err = orm.CreateSession(ctx, sessions.SessionRequest{
Email: initial.Email,
Password: cltest.Password,
WebAuthnConfig: sessions.WebAuthnConfiguration{
@@ -273,16 +280,17 @@ func TestORM_WebAuthn(t *testing.T) {
func TestOrm_GenerateAuthToken(t *testing.T) {
t.Parallel()
+ ctx := testutils.Context(t)
_, orm := setupORM(t)
initial := cltest.MustRandomUser(t)
- require.NoError(t, orm.CreateUser(&initial))
+ require.NoError(t, orm.CreateUser(ctx, &initial))
- token, err := orm.CreateAndSetAuthToken(&initial)
+ token, err := orm.CreateAndSetAuthToken(ctx, &initial)
require.NoError(t, err)
- dbUser, err := orm.FindUser(initial.Email)
+ dbUser, err := orm.FindUser(ctx, initial.Email)
require.NoError(t, err)
hashedSecret, err := auth.HashedSecret(token, dbUser.TokenSalt.String)
@@ -294,8 +302,8 @@ func TestOrm_GenerateAuthToken(t *testing.T) {
assert.Equal(t, dbUser.TokenKey.String, token.AccessKey)
assert.Equal(t, dbUser.TokenHashedSecret.String, hashedSecret)
- require.NoError(t, orm.DeleteAuthToken(&initial))
- dbUser, err = orm.FindUser(initial.Email)
+ require.NoError(t, orm.DeleteAuthToken(ctx, &initial))
+ dbUser, err = orm.FindUser(ctx, initial.Email)
require.NoError(t, err)
assert.Empty(t, dbUser.TokenKey.ValueOrZero())
assert.Empty(t, dbUser.TokenSalt.ValueOrZero())
diff --git a/core/sessions/localauth/reaper_test.go b/core/sessions/localauth/reaper_test.go
index fa9d882f743..47413c5fc62 100644
--- a/core/sessions/localauth/reaper_test.go
+++ b/core/sessions/localauth/reaper_test.go
@@ -11,6 +11,7 @@ import (
commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/logger/audit"
@@ -34,7 +35,7 @@ func TestSessionReaper_ReapSessions(t *testing.T) {
db := pgtest.NewSqlxDB(t)
config := sessionReaperConfig{}
lggr := logger.TestLogger(t)
- orm := localauth.NewORM(db, config.SessionTimeout().Duration(), lggr, pgtest.NewQConfig(true), audit.NoopLogger)
+ orm := localauth.NewORM(db, config.SessionTimeout().Duration(), lggr, audit.NoopLogger)
r := localauth.NewSessionReaper(db.DB, config, lggr)
t.Cleanup(func() {
@@ -55,6 +56,7 @@ func TestSessionReaper_ReapSessions(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ ctx := testutils.Context(t)
t.Cleanup(func() {
_, err2 := db.Exec("DELETE FROM sessions where email = $1", cltest.APIEmailAdmin)
require.NoError(t, err2)
@@ -67,13 +69,13 @@ func TestSessionReaper_ReapSessions(t *testing.T) {
if test.wantReap {
gomega.NewWithT(t).Eventually(func() []sessions.Session {
- sessions, err := orm.Sessions(0, 10)
+ sessions, err := orm.Sessions(ctx, 0, 10)
assert.NoError(t, err)
return sessions
}).Should(gomega.HaveLen(0))
} else {
gomega.NewWithT(t).Consistently(func() []sessions.Session {
- sessions, err := orm.Sessions(0, 10)
+ sessions, err := orm.Sessions(ctx, 0, 10)
assert.NoError(t, err)
return sessions
}).Should(gomega.HaveLen(1))
diff --git a/core/sessions/mocks/authentication_provider.go b/core/sessions/mocks/authentication_provider.go
index d1b846c318b..82be3a578d0 100644
--- a/core/sessions/mocks/authentication_provider.go
+++ b/core/sessions/mocks/authentication_provider.go
@@ -6,6 +6,8 @@ import (
auth "github.com/smartcontractkit/chainlink/v2/core/auth"
bridges "github.com/smartcontractkit/chainlink/v2/core/bridges"
+ context "context"
+
mock "github.com/stretchr/testify/mock"
sessions "github.com/smartcontractkit/chainlink/v2/core/sessions"
@@ -16,9 +18,9 @@ type AuthenticationProvider struct {
mock.Mock
}
-// AuthorizedUserWithSession provides a mock function with given fields: sessionID
-func (_m *AuthenticationProvider) AuthorizedUserWithSession(sessionID string) (sessions.User, error) {
- ret := _m.Called(sessionID)
+// AuthorizedUserWithSession provides a mock function with given fields: ctx, sessionID
+func (_m *AuthenticationProvider) AuthorizedUserWithSession(ctx context.Context, sessionID string) (sessions.User, error) {
+ ret := _m.Called(ctx, sessionID)
if len(ret) == 0 {
panic("no return value specified for AuthorizedUserWithSession")
@@ -26,17 +28,17 @@ func (_m *AuthenticationProvider) AuthorizedUserWithSession(sessionID string) (s
var r0 sessions.User
var r1 error
- if rf, ok := ret.Get(0).(func(string) (sessions.User, error)); ok {
- return rf(sessionID)
+ if rf, ok := ret.Get(0).(func(context.Context, string) (sessions.User, error)); ok {
+ return rf(ctx, sessionID)
}
- if rf, ok := ret.Get(0).(func(string) sessions.User); ok {
- r0 = rf(sessionID)
+ if rf, ok := ret.Get(0).(func(context.Context, string) sessions.User); ok {
+ r0 = rf(ctx, sessionID)
} else {
r0 = ret.Get(0).(sessions.User)
}
- if rf, ok := ret.Get(1).(func(string) error); ok {
- r1 = rf(sessionID)
+ if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+ r1 = rf(ctx, sessionID)
} else {
r1 = ret.Error(1)
}
@@ -44,17 +46,17 @@ func (_m *AuthenticationProvider) AuthorizedUserWithSession(sessionID string) (s
return r0, r1
}
-// ClearNonCurrentSessions provides a mock function with given fields: sessionID
-func (_m *AuthenticationProvider) ClearNonCurrentSessions(sessionID string) error {
- ret := _m.Called(sessionID)
+// ClearNonCurrentSessions provides a mock function with given fields: ctx, sessionID
+func (_m *AuthenticationProvider) ClearNonCurrentSessions(ctx context.Context, sessionID string) error {
+ ret := _m.Called(ctx, sessionID)
if len(ret) == 0 {
panic("no return value specified for ClearNonCurrentSessions")
}
var r0 error
- if rf, ok := ret.Get(0).(func(string) error); ok {
- r0 = rf(sessionID)
+ if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
+ r0 = rf(ctx, sessionID)
} else {
r0 = ret.Error(0)
}
@@ -62,9 +64,9 @@ func (_m *AuthenticationProvider) ClearNonCurrentSessions(sessionID string) erro
return r0
}
-// CreateAndSetAuthToken provides a mock function with given fields: user
-func (_m *AuthenticationProvider) CreateAndSetAuthToken(user *sessions.User) (*auth.Token, error) {
- ret := _m.Called(user)
+// CreateAndSetAuthToken provides a mock function with given fields: ctx, user
+func (_m *AuthenticationProvider) CreateAndSetAuthToken(ctx context.Context, user *sessions.User) (*auth.Token, error) {
+ ret := _m.Called(ctx, user)
if len(ret) == 0 {
panic("no return value specified for CreateAndSetAuthToken")
@@ -72,19 +74,19 @@ func (_m *AuthenticationProvider) CreateAndSetAuthToken(user *sessions.User) (*a
var r0 *auth.Token
var r1 error
- if rf, ok := ret.Get(0).(func(*sessions.User) (*auth.Token, error)); ok {
- return rf(user)
+ if rf, ok := ret.Get(0).(func(context.Context, *sessions.User) (*auth.Token, error)); ok {
+ return rf(ctx, user)
}
- if rf, ok := ret.Get(0).(func(*sessions.User) *auth.Token); ok {
- r0 = rf(user)
+ if rf, ok := ret.Get(0).(func(context.Context, *sessions.User) *auth.Token); ok {
+ r0 = rf(ctx, user)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*auth.Token)
}
}
- if rf, ok := ret.Get(1).(func(*sessions.User) error); ok {
- r1 = rf(user)
+ if rf, ok := ret.Get(1).(func(context.Context, *sessions.User) error); ok {
+ r1 = rf(ctx, user)
} else {
r1 = ret.Error(1)
}
@@ -92,9 +94,9 @@ func (_m *AuthenticationProvider) CreateAndSetAuthToken(user *sessions.User) (*a
return r0, r1
}
-// CreateSession provides a mock function with given fields: sr
-func (_m *AuthenticationProvider) CreateSession(sr sessions.SessionRequest) (string, error) {
- ret := _m.Called(sr)
+// CreateSession provides a mock function with given fields: ctx, sr
+func (_m *AuthenticationProvider) CreateSession(ctx context.Context, sr sessions.SessionRequest) (string, error) {
+ ret := _m.Called(ctx, sr)
if len(ret) == 0 {
panic("no return value specified for CreateSession")
@@ -102,17 +104,17 @@ func (_m *AuthenticationProvider) CreateSession(sr sessions.SessionRequest) (str
var r0 string
var r1 error
- if rf, ok := ret.Get(0).(func(sessions.SessionRequest) (string, error)); ok {
- return rf(sr)
+ if rf, ok := ret.Get(0).(func(context.Context, sessions.SessionRequest) (string, error)); ok {
+ return rf(ctx, sr)
}
- if rf, ok := ret.Get(0).(func(sessions.SessionRequest) string); ok {
- r0 = rf(sr)
+ if rf, ok := ret.Get(0).(func(context.Context, sessions.SessionRequest) string); ok {
+ r0 = rf(ctx, sr)
} else {
r0 = ret.Get(0).(string)
}
- if rf, ok := ret.Get(1).(func(sessions.SessionRequest) error); ok {
- r1 = rf(sr)
+ if rf, ok := ret.Get(1).(func(context.Context, sessions.SessionRequest) error); ok {
+ r1 = rf(ctx, sr)
} else {
r1 = ret.Error(1)
}
@@ -120,17 +122,17 @@ func (_m *AuthenticationProvider) CreateSession(sr sessions.SessionRequest) (str
return r0, r1
}
-// CreateUser provides a mock function with given fields: user
-func (_m *AuthenticationProvider) CreateUser(user *sessions.User) error {
- ret := _m.Called(user)
+// CreateUser provides a mock function with given fields: ctx, user
+func (_m *AuthenticationProvider) CreateUser(ctx context.Context, user *sessions.User) error {
+ ret := _m.Called(ctx, user)
if len(ret) == 0 {
panic("no return value specified for CreateUser")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*sessions.User) error); ok {
- r0 = rf(user)
+ if rf, ok := ret.Get(0).(func(context.Context, *sessions.User) error); ok {
+ r0 = rf(ctx, user)
} else {
r0 = ret.Error(0)
}
@@ -138,17 +140,17 @@ func (_m *AuthenticationProvider) CreateUser(user *sessions.User) error {
return r0
}
-// DeleteAuthToken provides a mock function with given fields: user
-func (_m *AuthenticationProvider) DeleteAuthToken(user *sessions.User) error {
- ret := _m.Called(user)
+// DeleteAuthToken provides a mock function with given fields: ctx, user
+func (_m *AuthenticationProvider) DeleteAuthToken(ctx context.Context, user *sessions.User) error {
+ ret := _m.Called(ctx, user)
if len(ret) == 0 {
panic("no return value specified for DeleteAuthToken")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*sessions.User) error); ok {
- r0 = rf(user)
+ if rf, ok := ret.Get(0).(func(context.Context, *sessions.User) error); ok {
+ r0 = rf(ctx, user)
} else {
r0 = ret.Error(0)
}
@@ -156,17 +158,17 @@ func (_m *AuthenticationProvider) DeleteAuthToken(user *sessions.User) error {
return r0
}
-// DeleteUser provides a mock function with given fields: email
-func (_m *AuthenticationProvider) DeleteUser(email string) error {
- ret := _m.Called(email)
+// DeleteUser provides a mock function with given fields: ctx, email
+func (_m *AuthenticationProvider) DeleteUser(ctx context.Context, email string) error {
+ ret := _m.Called(ctx, email)
if len(ret) == 0 {
panic("no return value specified for DeleteUser")
}
var r0 error
- if rf, ok := ret.Get(0).(func(string) error); ok {
- r0 = rf(email)
+ if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
+ r0 = rf(ctx, email)
} else {
r0 = ret.Error(0)
}
@@ -174,17 +176,17 @@ func (_m *AuthenticationProvider) DeleteUser(email string) error {
return r0
}
-// DeleteUserSession provides a mock function with given fields: sessionID
-func (_m *AuthenticationProvider) DeleteUserSession(sessionID string) error {
- ret := _m.Called(sessionID)
+// DeleteUserSession provides a mock function with given fields: ctx, sessionID
+func (_m *AuthenticationProvider) DeleteUserSession(ctx context.Context, sessionID string) error {
+ ret := _m.Called(ctx, sessionID)
if len(ret) == 0 {
panic("no return value specified for DeleteUserSession")
}
var r0 error
- if rf, ok := ret.Get(0).(func(string) error); ok {
- r0 = rf(sessionID)
+ if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
+ r0 = rf(ctx, sessionID)
} else {
r0 = ret.Error(0)
}
@@ -192,9 +194,9 @@ func (_m *AuthenticationProvider) DeleteUserSession(sessionID string) error {
return r0
}
-// FindExternalInitiator provides a mock function with given fields: eia
-func (_m *AuthenticationProvider) FindExternalInitiator(eia *auth.Token) (*bridges.ExternalInitiator, error) {
- ret := _m.Called(eia)
+// FindExternalInitiator provides a mock function with given fields: ctx, eia
+func (_m *AuthenticationProvider) FindExternalInitiator(ctx context.Context, eia *auth.Token) (*bridges.ExternalInitiator, error) {
+ ret := _m.Called(ctx, eia)
if len(ret) == 0 {
panic("no return value specified for FindExternalInitiator")
@@ -202,19 +204,19 @@ func (_m *AuthenticationProvider) FindExternalInitiator(eia *auth.Token) (*bridg
var r0 *bridges.ExternalInitiator
var r1 error
- if rf, ok := ret.Get(0).(func(*auth.Token) (*bridges.ExternalInitiator, error)); ok {
- return rf(eia)
+ if rf, ok := ret.Get(0).(func(context.Context, *auth.Token) (*bridges.ExternalInitiator, error)); ok {
+ return rf(ctx, eia)
}
- if rf, ok := ret.Get(0).(func(*auth.Token) *bridges.ExternalInitiator); ok {
- r0 = rf(eia)
+ if rf, ok := ret.Get(0).(func(context.Context, *auth.Token) *bridges.ExternalInitiator); ok {
+ r0 = rf(ctx, eia)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*bridges.ExternalInitiator)
}
}
- if rf, ok := ret.Get(1).(func(*auth.Token) error); ok {
- r1 = rf(eia)
+ if rf, ok := ret.Get(1).(func(context.Context, *auth.Token) error); ok {
+ r1 = rf(ctx, eia)
} else {
r1 = ret.Error(1)
}
@@ -222,9 +224,9 @@ func (_m *AuthenticationProvider) FindExternalInitiator(eia *auth.Token) (*bridg
return r0, r1
}
-// FindUser provides a mock function with given fields: email
-func (_m *AuthenticationProvider) FindUser(email string) (sessions.User, error) {
- ret := _m.Called(email)
+// FindUser provides a mock function with given fields: ctx, email
+func (_m *AuthenticationProvider) FindUser(ctx context.Context, email string) (sessions.User, error) {
+ ret := _m.Called(ctx, email)
if len(ret) == 0 {
panic("no return value specified for FindUser")
@@ -232,17 +234,17 @@ func (_m *AuthenticationProvider) FindUser(email string) (sessions.User, error)
var r0 sessions.User
var r1 error
- if rf, ok := ret.Get(0).(func(string) (sessions.User, error)); ok {
- return rf(email)
+ if rf, ok := ret.Get(0).(func(context.Context, string) (sessions.User, error)); ok {
+ return rf(ctx, email)
}
- if rf, ok := ret.Get(0).(func(string) sessions.User); ok {
- r0 = rf(email)
+ if rf, ok := ret.Get(0).(func(context.Context, string) sessions.User); ok {
+ r0 = rf(ctx, email)
} else {
r0 = ret.Get(0).(sessions.User)
}
- if rf, ok := ret.Get(1).(func(string) error); ok {
- r1 = rf(email)
+ if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+ r1 = rf(ctx, email)
} else {
r1 = ret.Error(1)
}
@@ -250,9 +252,9 @@ func (_m *AuthenticationProvider) FindUser(email string) (sessions.User, error)
return r0, r1
}
-// FindUserByAPIToken provides a mock function with given fields: apiToken
-func (_m *AuthenticationProvider) FindUserByAPIToken(apiToken string) (sessions.User, error) {
- ret := _m.Called(apiToken)
+// FindUserByAPIToken provides a mock function with given fields: ctx, apiToken
+func (_m *AuthenticationProvider) FindUserByAPIToken(ctx context.Context, apiToken string) (sessions.User, error) {
+ ret := _m.Called(ctx, apiToken)
if len(ret) == 0 {
panic("no return value specified for FindUserByAPIToken")
@@ -260,17 +262,17 @@ func (_m *AuthenticationProvider) FindUserByAPIToken(apiToken string) (sessions.
var r0 sessions.User
var r1 error
- if rf, ok := ret.Get(0).(func(string) (sessions.User, error)); ok {
- return rf(apiToken)
+ if rf, ok := ret.Get(0).(func(context.Context, string) (sessions.User, error)); ok {
+ return rf(ctx, apiToken)
}
- if rf, ok := ret.Get(0).(func(string) sessions.User); ok {
- r0 = rf(apiToken)
+ if rf, ok := ret.Get(0).(func(context.Context, string) sessions.User); ok {
+ r0 = rf(ctx, apiToken)
} else {
r0 = ret.Get(0).(sessions.User)
}
- if rf, ok := ret.Get(1).(func(string) error); ok {
- r1 = rf(apiToken)
+ if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+ r1 = rf(ctx, apiToken)
} else {
r1 = ret.Error(1)
}
@@ -278,9 +280,9 @@ func (_m *AuthenticationProvider) FindUserByAPIToken(apiToken string) (sessions.
return r0, r1
}
-// GetUserWebAuthn provides a mock function with given fields: email
-func (_m *AuthenticationProvider) GetUserWebAuthn(email string) ([]sessions.WebAuthn, error) {
- ret := _m.Called(email)
+// GetUserWebAuthn provides a mock function with given fields: ctx, email
+func (_m *AuthenticationProvider) GetUserWebAuthn(ctx context.Context, email string) ([]sessions.WebAuthn, error) {
+ ret := _m.Called(ctx, email)
if len(ret) == 0 {
panic("no return value specified for GetUserWebAuthn")
@@ -288,19 +290,19 @@ func (_m *AuthenticationProvider) GetUserWebAuthn(email string) ([]sessions.WebA
var r0 []sessions.WebAuthn
var r1 error
- if rf, ok := ret.Get(0).(func(string) ([]sessions.WebAuthn, error)); ok {
- return rf(email)
+ if rf, ok := ret.Get(0).(func(context.Context, string) ([]sessions.WebAuthn, error)); ok {
+ return rf(ctx, email)
}
- if rf, ok := ret.Get(0).(func(string) []sessions.WebAuthn); ok {
- r0 = rf(email)
+ if rf, ok := ret.Get(0).(func(context.Context, string) []sessions.WebAuthn); ok {
+ r0 = rf(ctx, email)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]sessions.WebAuthn)
}
}
- if rf, ok := ret.Get(1).(func(string) error); ok {
- r1 = rf(email)
+ if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+ r1 = rf(ctx, email)
} else {
r1 = ret.Error(1)
}
@@ -308,9 +310,9 @@ func (_m *AuthenticationProvider) GetUserWebAuthn(email string) ([]sessions.WebA
return r0, r1
}
-// ListUsers provides a mock function with given fields:
-func (_m *AuthenticationProvider) ListUsers() ([]sessions.User, error) {
- ret := _m.Called()
+// ListUsers provides a mock function with given fields: ctx
+func (_m *AuthenticationProvider) ListUsers(ctx context.Context) ([]sessions.User, error) {
+ ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for ListUsers")
@@ -318,19 +320,19 @@ func (_m *AuthenticationProvider) ListUsers() ([]sessions.User, error) {
var r0 []sessions.User
var r1 error
- if rf, ok := ret.Get(0).(func() ([]sessions.User, error)); ok {
- return rf()
+ if rf, ok := ret.Get(0).(func(context.Context) ([]sessions.User, error)); ok {
+ return rf(ctx)
}
- if rf, ok := ret.Get(0).(func() []sessions.User); ok {
- r0 = rf()
+ if rf, ok := ret.Get(0).(func(context.Context) []sessions.User); ok {
+ r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]sessions.User)
}
}
- if rf, ok := ret.Get(1).(func() error); ok {
- r1 = rf()
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
@@ -338,17 +340,17 @@ func (_m *AuthenticationProvider) ListUsers() ([]sessions.User, error) {
return r0, r1
}
-// SaveWebAuthn provides a mock function with given fields: token
-func (_m *AuthenticationProvider) SaveWebAuthn(token *sessions.WebAuthn) error {
- ret := _m.Called(token)
+// SaveWebAuthn provides a mock function with given fields: ctx, token
+func (_m *AuthenticationProvider) SaveWebAuthn(ctx context.Context, token *sessions.WebAuthn) error {
+ ret := _m.Called(ctx, token)
if len(ret) == 0 {
panic("no return value specified for SaveWebAuthn")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*sessions.WebAuthn) error); ok {
- r0 = rf(token)
+ if rf, ok := ret.Get(0).(func(context.Context, *sessions.WebAuthn) error); ok {
+ r0 = rf(ctx, token)
} else {
r0 = ret.Error(0)
}
@@ -356,9 +358,9 @@ func (_m *AuthenticationProvider) SaveWebAuthn(token *sessions.WebAuthn) error {
return r0
}
-// Sessions provides a mock function with given fields: offset, limit
-func (_m *AuthenticationProvider) Sessions(offset int, limit int) ([]sessions.Session, error) {
- ret := _m.Called(offset, limit)
+// Sessions provides a mock function with given fields: ctx, offset, limit
+func (_m *AuthenticationProvider) Sessions(ctx context.Context, offset int, limit int) ([]sessions.Session, error) {
+ ret := _m.Called(ctx, offset, limit)
if len(ret) == 0 {
panic("no return value specified for Sessions")
@@ -366,19 +368,19 @@ func (_m *AuthenticationProvider) Sessions(offset int, limit int) ([]sessions.Se
var r0 []sessions.Session
var r1 error
- if rf, ok := ret.Get(0).(func(int, int) ([]sessions.Session, error)); ok {
- return rf(offset, limit)
+ if rf, ok := ret.Get(0).(func(context.Context, int, int) ([]sessions.Session, error)); ok {
+ return rf(ctx, offset, limit)
}
- if rf, ok := ret.Get(0).(func(int, int) []sessions.Session); ok {
- r0 = rf(offset, limit)
+ if rf, ok := ret.Get(0).(func(context.Context, int, int) []sessions.Session); ok {
+ r0 = rf(ctx, offset, limit)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]sessions.Session)
}
}
- if rf, ok := ret.Get(1).(func(int, int) error); ok {
- r1 = rf(offset, limit)
+ if rf, ok := ret.Get(1).(func(context.Context, int, int) error); ok {
+ r1 = rf(ctx, offset, limit)
} else {
r1 = ret.Error(1)
}
@@ -386,17 +388,17 @@ func (_m *AuthenticationProvider) Sessions(offset int, limit int) ([]sessions.Se
return r0, r1
}
-// SetAuthToken provides a mock function with given fields: user, token
-func (_m *AuthenticationProvider) SetAuthToken(user *sessions.User, token *auth.Token) error {
- ret := _m.Called(user, token)
+// SetAuthToken provides a mock function with given fields: ctx, user, token
+func (_m *AuthenticationProvider) SetAuthToken(ctx context.Context, user *sessions.User, token *auth.Token) error {
+ ret := _m.Called(ctx, user, token)
if len(ret) == 0 {
panic("no return value specified for SetAuthToken")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*sessions.User, *auth.Token) error); ok {
- r0 = rf(user, token)
+ if rf, ok := ret.Get(0).(func(context.Context, *sessions.User, *auth.Token) error); ok {
+ r0 = rf(ctx, user, token)
} else {
r0 = ret.Error(0)
}
@@ -404,17 +406,17 @@ func (_m *AuthenticationProvider) SetAuthToken(user *sessions.User, token *auth.
return r0
}
-// SetPassword provides a mock function with given fields: user, newPassword
-func (_m *AuthenticationProvider) SetPassword(user *sessions.User, newPassword string) error {
- ret := _m.Called(user, newPassword)
+// SetPassword provides a mock function with given fields: ctx, user, newPassword
+func (_m *AuthenticationProvider) SetPassword(ctx context.Context, user *sessions.User, newPassword string) error {
+ ret := _m.Called(ctx, user, newPassword)
if len(ret) == 0 {
panic("no return value specified for SetPassword")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*sessions.User, string) error); ok {
- r0 = rf(user, newPassword)
+ if rf, ok := ret.Get(0).(func(context.Context, *sessions.User, string) error); ok {
+ r0 = rf(ctx, user, newPassword)
} else {
r0 = ret.Error(0)
}
@@ -422,17 +424,17 @@ func (_m *AuthenticationProvider) SetPassword(user *sessions.User, newPassword s
return r0
}
-// TestPassword provides a mock function with given fields: email, password
-func (_m *AuthenticationProvider) TestPassword(email string, password string) error {
- ret := _m.Called(email, password)
+// TestPassword provides a mock function with given fields: ctx, email, password
+func (_m *AuthenticationProvider) TestPassword(ctx context.Context, email string, password string) error {
+ ret := _m.Called(ctx, email, password)
if len(ret) == 0 {
panic("no return value specified for TestPassword")
}
var r0 error
- if rf, ok := ret.Get(0).(func(string, string) error); ok {
- r0 = rf(email, password)
+ if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok {
+ r0 = rf(ctx, email, password)
} else {
r0 = ret.Error(0)
}
@@ -440,9 +442,9 @@ func (_m *AuthenticationProvider) TestPassword(email string, password string) er
return r0
}
-// UpdateRole provides a mock function with given fields: email, newRole
-func (_m *AuthenticationProvider) UpdateRole(email string, newRole string) (sessions.User, error) {
- ret := _m.Called(email, newRole)
+// UpdateRole provides a mock function with given fields: ctx, email, newRole
+func (_m *AuthenticationProvider) UpdateRole(ctx context.Context, email string, newRole string) (sessions.User, error) {
+ ret := _m.Called(ctx, email, newRole)
if len(ret) == 0 {
panic("no return value specified for UpdateRole")
@@ -450,17 +452,17 @@ func (_m *AuthenticationProvider) UpdateRole(email string, newRole string) (sess
var r0 sessions.User
var r1 error
- if rf, ok := ret.Get(0).(func(string, string) (sessions.User, error)); ok {
- return rf(email, newRole)
+ if rf, ok := ret.Get(0).(func(context.Context, string, string) (sessions.User, error)); ok {
+ return rf(ctx, email, newRole)
}
- if rf, ok := ret.Get(0).(func(string, string) sessions.User); ok {
- r0 = rf(email, newRole)
+ if rf, ok := ret.Get(0).(func(context.Context, string, string) sessions.User); ok {
+ r0 = rf(ctx, email, newRole)
} else {
r0 = ret.Get(0).(sessions.User)
}
- if rf, ok := ret.Get(1).(func(string, string) error); ok {
- r1 = rf(email, newRole)
+ if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
+ r1 = rf(ctx, email, newRole)
} else {
r1 = ret.Error(1)
}
diff --git a/core/sessions/mocks/basic_admin_users_orm.go b/core/sessions/mocks/basic_admin_users_orm.go
index 44ee0b1f705..dc9c40a62c0 100644
--- a/core/sessions/mocks/basic_admin_users_orm.go
+++ b/core/sessions/mocks/basic_admin_users_orm.go
@@ -3,6 +3,8 @@
package mocks
import (
+ context "context"
+
sessions "github.com/smartcontractkit/chainlink/v2/core/sessions"
mock "github.com/stretchr/testify/mock"
)
@@ -12,17 +14,17 @@ type BasicAdminUsersORM struct {
mock.Mock
}
-// CreateUser provides a mock function with given fields: user
-func (_m *BasicAdminUsersORM) CreateUser(user *sessions.User) error {
- ret := _m.Called(user)
+// CreateUser provides a mock function with given fields: ctx, user
+func (_m *BasicAdminUsersORM) CreateUser(ctx context.Context, user *sessions.User) error {
+ ret := _m.Called(ctx, user)
if len(ret) == 0 {
panic("no return value specified for CreateUser")
}
var r0 error
- if rf, ok := ret.Get(0).(func(*sessions.User) error); ok {
- r0 = rf(user)
+ if rf, ok := ret.Get(0).(func(context.Context, *sessions.User) error); ok {
+ r0 = rf(ctx, user)
} else {
r0 = ret.Error(0)
}
@@ -30,9 +32,9 @@ func (_m *BasicAdminUsersORM) CreateUser(user *sessions.User) error {
return r0
}
-// FindUser provides a mock function with given fields: email
-func (_m *BasicAdminUsersORM) FindUser(email string) (sessions.User, error) {
- ret := _m.Called(email)
+// FindUser provides a mock function with given fields: ctx, email
+func (_m *BasicAdminUsersORM) FindUser(ctx context.Context, email string) (sessions.User, error) {
+ ret := _m.Called(ctx, email)
if len(ret) == 0 {
panic("no return value specified for FindUser")
@@ -40,17 +42,17 @@ func (_m *BasicAdminUsersORM) FindUser(email string) (sessions.User, error) {
var r0 sessions.User
var r1 error
- if rf, ok := ret.Get(0).(func(string) (sessions.User, error)); ok {
- return rf(email)
+ if rf, ok := ret.Get(0).(func(context.Context, string) (sessions.User, error)); ok {
+ return rf(ctx, email)
}
- if rf, ok := ret.Get(0).(func(string) sessions.User); ok {
- r0 = rf(email)
+ if rf, ok := ret.Get(0).(func(context.Context, string) sessions.User); ok {
+ r0 = rf(ctx, email)
} else {
r0 = ret.Get(0).(sessions.User)
}
- if rf, ok := ret.Get(1).(func(string) error); ok {
- r1 = rf(email)
+ if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+ r1 = rf(ctx, email)
} else {
r1 = ret.Error(1)
}
@@ -58,9 +60,9 @@ func (_m *BasicAdminUsersORM) FindUser(email string) (sessions.User, error) {
return r0, r1
}
-// ListUsers provides a mock function with given fields:
-func (_m *BasicAdminUsersORM) ListUsers() ([]sessions.User, error) {
- ret := _m.Called()
+// ListUsers provides a mock function with given fields: ctx
+func (_m *BasicAdminUsersORM) ListUsers(ctx context.Context) ([]sessions.User, error) {
+ ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for ListUsers")
@@ -68,19 +70,19 @@ func (_m *BasicAdminUsersORM) ListUsers() ([]sessions.User, error) {
var r0 []sessions.User
var r1 error
- if rf, ok := ret.Get(0).(func() ([]sessions.User, error)); ok {
- return rf()
+ if rf, ok := ret.Get(0).(func(context.Context) ([]sessions.User, error)); ok {
+ return rf(ctx)
}
- if rf, ok := ret.Get(0).(func() []sessions.User); ok {
- r0 = rf()
+ if rf, ok := ret.Get(0).(func(context.Context) []sessions.User); ok {
+ r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]sessions.User)
}
}
- if rf, ok := ret.Get(1).(func() error); ok {
- r1 = rf()
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
diff --git a/core/sessions/webauthn.go b/core/sessions/webauthn.go
index c959bec08de..a1c01a446cd 100644
--- a/core/sessions/webauthn.go
+++ b/core/sessions/webauthn.go
@@ -1,6 +1,7 @@
package sessions
import (
+ "context"
"encoding/json"
"fmt"
"net/http"
@@ -279,7 +280,7 @@ func (store *WebAuthnSessionStore) GetWebauthnSession(key string) (data webauthn
return
}
-func AddCredentialToUser(ap AuthenticationProvider, email string, credential *webauthn.Credential) error {
+func AddCredentialToUser(ctx context.Context, ap AuthenticationProvider, email string, credential *webauthn.Credential) error {
credj, err := json.Marshal(credential)
if err != nil {
return err
@@ -289,5 +290,5 @@ func AddCredentialToUser(ap AuthenticationProvider, email string, credential *we
Email: email,
PublicKeyData: sqlxTypes.JSONText(credj),
}
- return ap.SaveWebAuthn(&token)
+ return ap.SaveWebAuthn(ctx, &token)
}
diff --git a/core/store/migrate/migrate_test.go b/core/store/migrate/migrate_test.go
index 286e1b3a295..b3a15123efa 100644
--- a/core/store/migrate/migrate_test.go
+++ b/core/store/migrate/migrate_test.go
@@ -78,14 +78,15 @@ func TestMigrate_0100_BootstrapConfigs(t *testing.T) {
err := goose.UpTo(db.DB, migrationDir, 99)
require.NoError(t, err)
- pipelineORM := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
- pipelineID, err := pipelineORM.CreateSpec(pipeline.Pipeline{}, 0)
+ pipelineORM := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns())
+ ctx := testutils.Context(t)
+ pipelineID, err := pipelineORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, 0)
require.NoError(t, err)
- pipelineID2, err := pipelineORM.CreateSpec(pipeline.Pipeline{}, 0)
+ pipelineID2, err := pipelineORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, 0)
require.NoError(t, err)
- nonBootstrapPipelineID, err := pipelineORM.CreateSpec(pipeline.Pipeline{}, 0)
+ nonBootstrapPipelineID, err := pipelineORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, 0)
require.NoError(t, err)
- newFormatBoostrapPipelineID2, err := pipelineORM.CreateSpec(pipeline.Pipeline{}, 0)
+ newFormatBoostrapPipelineID2, err := pipelineORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, 0)
require.NoError(t, err)
// OCR2 struct at migration v0099
diff --git a/core/store/migrate/migrations/0232_add_workflow_spec.sql b/core/store/migrate/migrations/0232_add_workflow_spec.sql
new file mode 100644
index 00000000000..8b9a049ed41
--- /dev/null
+++ b/core/store/migrate/migrations/0232_add_workflow_spec.sql
@@ -0,0 +1,63 @@
+-- +goose Up
+-- +goose StatementBegin
+CREATE TABLE workflow_specs (
+ id SERIAL PRIMARY KEY,
+ workflow_id varchar(64) NOT NULL,
+ workflow text NOT NULL,
+ workflow_owner varchar(40) NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL
+);
+
+ALTER TABLE jobs
+ ADD COLUMN workflow_spec_id INT REFERENCES workflow_specs (id),
+ DROP CONSTRAINT chk_specs;
+
+ALTER TABLE jobs
+ ADD CONSTRAINT chk_specs CHECK (
+ num_nonnulls(
+ ocr_oracle_spec_id, ocr2_oracle_spec_id,
+ direct_request_spec_id, flux_monitor_spec_id,
+ keeper_spec_id, cron_spec_id, webhook_spec_id,
+ vrf_spec_id, blockhash_store_spec_id,
+ block_header_feeder_spec_id, bootstrap_spec_id,
+ gateway_spec_id,
+ legacy_gas_station_server_spec_id,
+ legacy_gas_station_sidecar_spec_id,
+ eal_spec_id,
+ workflow_spec_id,
+ CASE "type"
+ WHEN 'stream'
+ THEN 1
+ ELSE NULL
+ END -- 'stream' type lacks a spec but should not cause validation to fail
+ ) = 1
+ );
+-- +goose StatementEnd
+
+-- +goose Down
+
+-- +goose StatementBegin
+ALTER TABLE jobs
+ DROP CONSTRAINT chk_specs,
+ ADD CONSTRAINT chk_specs CHECK (
+ num_nonnulls(
+ ocr_oracle_spec_id, ocr2_oracle_spec_id,
+ direct_request_spec_id, flux_monitor_spec_id,
+ keeper_spec_id, cron_spec_id, webhook_spec_id,
+ vrf_spec_id, blockhash_store_spec_id,
+ block_header_feeder_spec_id, bootstrap_spec_id,
+ gateway_spec_id,
+ legacy_gas_station_server_spec_id,
+ legacy_gas_station_sidecar_spec_id,
+ eal_spec_id,
+ CASE "type" WHEN 'stream' THEN 1 ELSE NULL END, -- 'stream' type lacks a spec but should not cause validation to fail
+ CASE "type" WHEN 'workflow' THEN 1 ELSE NULL END -- 'workflow' type lacks a spec but should not cause validation to fail
+ ) = 1
+ );
+
+ALTER TABLE jobs
+ DROP COLUMN workflow_spec_id;
+
+DROP TABLE workflow_specs;
+-- +goose StatementEnd
diff --git a/core/store/migrate/migrations/0233_log_poller_word_topic_indexes.sql b/core/store/migrate/migrations/0233_log_poller_word_topic_indexes.sql
new file mode 100644
index 00000000000..e155e207996
--- /dev/null
+++ b/core/store/migrate/migrations/0233_log_poller_word_topic_indexes.sql
@@ -0,0 +1,65 @@
+-- +goose Up
+
+drop index if exists evm.evm_logs_idx_data_word_one;
+drop index if exists evm.evm_logs_idx_data_word_two;
+drop index if exists evm.evm_logs_idx_data_word_three;
+drop index if exists evm.evm_logs_idx_data_word_four;
+drop index if exists evm.evm_logs_idx_topic_two;
+drop index if exists evm.evm_logs_idx_topic_three;
+drop index if exists evm.evm_logs_idx_topic_four;
+
+create index evm_logs_idx_data_word_one
+ on evm.logs (address, event_sig, evm_chain_id, "substring"(data, 1, 32));
+
+create index evm_logs_idx_data_word_two
+ on evm.logs (address, event_sig, evm_chain_id, "substring"(data, 33, 32));
+
+create index evm_logs_idx_data_word_three
+ on evm.logs (address, event_sig, evm_chain_id, "substring"(data, 65, 32));
+
+create index evm_logs_idx_data_word_four
+ on evm.logs (address, event_sig, evm_chain_id, "substring"(data, 97, 32));
+
+create index evm_logs_idx_data_word_five
+ on evm.logs (address, event_sig, evm_chain_id, "substring"(data, 129, 32));
+
+create index evm_logs_idx_topic_two
+ on evm.logs (address, event_sig, evm_chain_id, (topics[2]));
+
+create index evm_logs_idx_topic_three
+ on evm.logs (address, event_sig, evm_chain_id, (topics[3]));
+
+create index evm_logs_idx_topic_four
+ on evm.logs (address, event_sig, evm_chain_id, (topics[4]));
+
+-- +goose Down
+
+drop index if exists evm.evm_logs_idx_data_word_one;
+drop index if exists evm.evm_logs_idx_data_word_two;
+drop index if exists evm.evm_logs_idx_data_word_three;
+drop index if exists evm.evm_logs_idx_data_word_four;
+drop index if exists evm.evm_logs_idx_data_word_five;
+drop index if exists evm.evm_logs_idx_topic_two;
+drop index if exists evm.evm_logs_idx_topic_three;
+drop index if exists evm.evm_logs_idx_topic_four;
+
+create index evm_logs_idx_data_word_one
+ on evm.logs ("substring"(data, 1, 32));
+
+create index evm_logs_idx_data_word_two
+ on evm.logs ("substring"(data, 33, 32));
+
+create index evm_logs_idx_data_word_three
+ on evm.logs ("substring"(data, 65, 32));
+
+create index evm_logs_idx_data_word_four
+ on evm.logs ("substring"(data, 97, 32));
+
+create index evm_logs_idx_topic_two
+ on evm.logs ((topics[2]));
+
+create index evm_logs_idx_topic_three
+ on evm.logs ((topics[3]));
+
+create index evm_logs_idx_topic_four
+ on evm.logs ((topics[4]));
\ No newline at end of file
diff --git a/core/testdata/testspecs/v2_specs.go b/core/testdata/testspecs/v2_specs.go
index 5ca79f1abb4..a0d8ea863e2 100644
--- a/core/testdata/testspecs/v2_specs.go
+++ b/core/testdata/testspecs/v2_specs.go
@@ -863,3 +863,26 @@ ds -> ds_parse -> ds_multiply;
toml := fmt.Sprintf(template, params.Name, params.StreamID)
return StreamSpec{StreamSpecParams: params, toml: toml}
}
+
+type WorkflowSpec struct {
+ toml string
+}
+
+func (w WorkflowSpec) Toml() string {
+ return w.toml
+}
+
+func GenerateWorkflowSpec(id, owner, spec string) WorkflowSpec {
+ template := `
+type = "workflow"
+schemaVersion = 1
+name = "test-spec"
+workflowId = "%s"
+workflowOwner = "%s"
+workflow = """
+%s
+"""
+`
+ toml := fmt.Sprintf(template, id, owner, spec)
+ return WorkflowSpec{toml: toml}
+}
diff --git a/core/web/assets/index.html b/core/web/assets/index.html
index c79e099904f..007152e132c 100644
--- a/core/web/assets/index.html
+++ b/core/web/assets/index.html
@@ -1 +1 @@
-Operator UIChainlink
\ No newline at end of file
+Operator UIChainlink
\ No newline at end of file
diff --git a/core/web/assets/index.html.gz b/core/web/assets/index.html.gz
index 520ebac6e87..0cd3a7575b4 100644
Binary files a/core/web/assets/index.html.gz and b/core/web/assets/index.html.gz differ
diff --git a/core/web/assets/main.4a9b933093bb165fcc8f.js b/core/web/assets/main.22957d5aeebe77369ec3.js
similarity index 91%
rename from core/web/assets/main.4a9b933093bb165fcc8f.js
rename to core/web/assets/main.22957d5aeebe77369ec3.js
index 33f59a7826b..2fe73fb8cab 100644
--- a/core/web/assets/main.4a9b933093bb165fcc8f.js
+++ b/core/web/assets/main.22957d5aeebe77369ec3.js
@@ -184,4 +184,4 @@ object-assign
*/ Object.defineProperty(t,"__esModule",{value:!0}),"undefined"==typeof window||"function"!=typeof MessageChannel){var n,r,i,a,o,s=null,u=null,c=function(){if(null!==s)try{var e=t.unstable_now();s(!0,e),s=null}catch(n){throw setTimeout(c,0),n}},l=Date.now();t.unstable_now=function(){return Date.now()-l},n=function(e){null!==s?setTimeout(n,0,e):(s=e,setTimeout(c,0))},r=function(e,t){u=setTimeout(e,t)},i=function(){clearTimeout(u)},a=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,h=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var b=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof b&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var m=d.now();t.unstable_now=function(){return d.now()-m}}var g=!1,v=null,y=-1,w=5,_=0;a=function(){return t.unstable_now()>=_},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125M(o,n))void 0!==u&&0>M(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[a]=n,r=a);else if(void 0!==u&&0>M(u,n))e[r]=u,e[s]=n,r=s;else break a}}return t}return null}function M(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var O=[],A=[],L=1,C=null,I=3,D=!1,N=!1,P=!1;function R(e){for(var t=x(A);null!==t;){if(null===t.callback)T(A);else if(t.startTime<=e)T(A),t.sortIndex=t.expirationTime,k(O,t);else break;t=x(A)}}function j(e){if(P=!1,R(e),!N){if(null!==x(O))N=!0,n(F);else{var t=x(A);null!==t&&r(j,t.startTime-e)}}}function F(e,n){N=!1,P&&(P=!1,i()),D=!0;var o=I;try{for(R(n),C=x(O);null!==C&&(!(C.expirationTime>n)||e&&!a());){var s=C.callback;if(null!==s){C.callback=null,I=C.priorityLevel;var u=s(C.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?C.callback=u:C===x(O)&&T(O),R(n)}else T(O);C=x(O)}if(null!==C)var c=!0;else{var l=x(A);null!==l&&r(j,l.startTime-n),c=!1}return c}finally{C=null,I=o,D=!1}}function Y(e){switch(e){case 1:return -1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=o;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=I;I=e;try{return t()}finally{I=n}},t.unstable_next=function(e){switch(I){case 1:case 2:case 3:var t=3;break;default:t=I}var n=I;I=t;try{return e()}finally{I=n}},t.unstable_scheduleCallback=function(e,a,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0s?(e.sortIndex=u,k(A,e),null===x(O)&&e===x(A)&&(P?i():P=!0,r(j,u-s))):(e.sortIndex=o,k(O,e),N||D||(N=!0,n(F))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=I;return function(){var n=I;I=t;try{return e.apply(this,arguments)}finally{I=n}}},t.unstable_getCurrentPriorityLevel=function(){return I},t.unstable_shouldYield=function(){var e=t.unstable_now();R(e);var n=x(O);return n!==C&&null!==C&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function c(e,t,n){var r=t.length-1;if(r=0?(i>0&&(e.lastNeed=i-1),i):--r=0?(i>0&&(e.lastNeed=i-2),i):--r=0?(i>0&&(2===i?i=0:e.lastNeed=i-3),i):0}function l(e,t,n){if((192&t[0])!=128)return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if((192&t[1])!=128)return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&(192&t[2])!=128)return e.lastNeed=2,"�"}}function f(e){var t=this.lastTotal-this.lastNeed,n=l(this,e,t);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):void(e.copy(this.lastChar,t,0,e.length),this.lastNeed-=e.length)}function d(e,t){var n=c(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)}function h(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+"�":t}function p(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function b(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function m(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function g(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function v(e){return e.toString(this.encoding)}function y(e){return e&&e.length?this.write(e):""}t.s=s,s.prototype.write=function(e){var t,n;if(0===e.length)return"";if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return nOF});var r,i,a,o,s,u,c,l=n(67294),f=n.t(l,2),d=n(97779),h=n(47886),p=n(57209),b=n(32316),m=n(95880),g=n(17051),v=n(71381),y=n(81701),w=n(3022),_=n(60323),E=n(87591),S=n(25649),k=n(28902),x=n(71426),T=n(48884),M=n(94184),O=n.n(M),A=n(55977),L=n(73935),C=function(){if("undefined"!=typeof Map)return Map;function e(e,t){var n=-1;return e.some(function(e,r){return e[0]===t&&(n=r,!0)}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(t){var n=e(this.__entries__,t),r=this.__entries__[n];return r&&r[1]},t.prototype.set=function(t,n){var r=e(this.__entries__,t);~r?this.__entries__[r][1]=n:this.__entries__.push([t,n])},t.prototype.delete=function(t){var n=this.__entries__,r=e(n,t);~r&&n.splice(r,1)},t.prototype.has=function(t){return!!~e(this.__entries__,t)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(e,t){void 0===t&&(t=null);for(var n=0,r=this.__entries__;n0},e.prototype.connect_=function(){I&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Y?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){I&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t;F.some(function(e){return!!~n.indexOf(e)})&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),U=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),er="undefined"!=typeof WeakMap?new WeakMap:new C,ei=function(){function e(t){if(!(this instanceof e))throw TypeError("Cannot call a class as a function.");if(!arguments.length)throw TypeError("1 argument required, but only 0 present.");var n=B.getInstance(),r=new en(t,n,this);er.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){ei.prototype[e]=function(){var t;return(t=er.get(this))[e].apply(t,arguments)}});var ea=void 0!==D.ResizeObserver?D.ResizeObserver:ei;let eo=ea;var es=function(e){var t=[],n=null,r=function(){for(var r=arguments.length,i=Array(r),a=0;a=t||n<0||f&&r>=a}function g(){var e=eb();if(m(e))return v(e);s=setTimeout(g,b(e))}function v(e){return(s=void 0,d&&r)?h(e):(r=i=void 0,o)}function y(){void 0!==s&&clearTimeout(s),c=0,r=u=i=s=void 0}function w(){return void 0===s?o:v(eb())}function _(){var e=eb(),n=m(e);if(r=arguments,i=this,u=e,n){if(void 0===s)return p(u);if(f)return clearTimeout(s),s=setTimeout(g,t),h(u)}return void 0===s&&(s=setTimeout(g,t)),o}return t=ez(t)||0,ed(n)&&(l=!!n.leading,a=(f="maxWait"in n)?eW(ez(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),_.cancel=y,_.flush=w,_}let eq=eV;var eZ="Expected a function";function eX(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw TypeError(eZ);return ed(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),eq(e,t,{leading:r,maxWait:t,trailing:i})}let eJ=eX;var eQ={debounce:eq,throttle:eJ},e1=function(e){return eQ[e]},e0=function(e){return"function"==typeof e},e2=function(){return"undefined"==typeof window},e3=function(e){return e instanceof Element||e instanceof HTMLDocument};function e4(e){return(e4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function e5(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function e6(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&l.createElement(tG.Z,{variant:"indeterminate",classes:r}))};tK.propTypes={fetchCount:el().number.isRequired};let tV=(0,b.withStyles)(tW)(tK);var tq=n(5536);let tZ=n.p+"ba8bbf16ebf8e1d05bef.svg";function tX(){return(tX=Object.assign||function(e){for(var t=1;t120){for(var d=Math.floor(u/80),h=u%80,p=[],b=0;b0},name:{enumerable:!1},nodes:{enumerable:!1},source:{enumerable:!1},positions:{enumerable:!1},originalError:{enumerable:!1}}),null!=s&&s.stack)?(Object.defineProperty(nf(b),"stack",{value:s.stack,writable:!0,configurable:!0}),nl(b)):(Error.captureStackTrace?Error.captureStackTrace(nf(b),n):Object.defineProperty(nf(b),"stack",{value:Error().stack,writable:!0,configurable:!0}),b)}return ns(n,[{key:"toString",value:function(){return nw(this)}},{key:t4.YF,get:function(){return"Object"}}]),n}(nd(Error));function ny(e){return void 0===e||0===e.length?void 0:e}function nw(e){var t=e.message;if(e.nodes)for(var n=0,r=e.nodes;n",EOF:"",BANG:"!",DOLLAR:"$",AMP:"&",PAREN_L:"(",PAREN_R:")",SPREAD:"...",COLON:":",EQUALS:"=",AT:"@",BRACKET_L:"[",BRACKET_R:"]",BRACE_L:"{",PIPE:"|",BRACE_R:"}",NAME:"Name",INT:"Int",FLOAT:"Float",STRING:"String",BLOCK_STRING:"BlockString",COMMENT:"Comment"}),nx=n(10143),nT=Object.freeze({QUERY:"QUERY",MUTATION:"MUTATION",SUBSCRIPTION:"SUBSCRIPTION",FIELD:"FIELD",FRAGMENT_DEFINITION:"FRAGMENT_DEFINITION",FRAGMENT_SPREAD:"FRAGMENT_SPREAD",INLINE_FRAGMENT:"INLINE_FRAGMENT",VARIABLE_DEFINITION:"VARIABLE_DEFINITION",SCHEMA:"SCHEMA",SCALAR:"SCALAR",OBJECT:"OBJECT",FIELD_DEFINITION:"FIELD_DEFINITION",ARGUMENT_DEFINITION:"ARGUMENT_DEFINITION",INTERFACE:"INTERFACE",UNION:"UNION",ENUM:"ENUM",ENUM_VALUE:"ENUM_VALUE",INPUT_OBJECT:"INPUT_OBJECT",INPUT_FIELD_DEFINITION:"INPUT_FIELD_DEFINITION"}),nM=n(87392),nO=function(){function e(e){var t=new nS.WU(nk.SOF,0,0,0,0,null);this.source=e,this.lastToken=t,this.token=t,this.line=1,this.lineStart=0}var t=e.prototype;return t.advance=function(){return this.lastToken=this.token,this.token=this.lookahead()},t.lookahead=function(){var e,t=this.token;if(t.kind!==nk.EOF)do t=null!==(e=t.next)&&void 0!==e?e:t.next=nC(this,t);while(t.kind===nk.COMMENT)return t},e}();function nA(e){return e===nk.BANG||e===nk.DOLLAR||e===nk.AMP||e===nk.PAREN_L||e===nk.PAREN_R||e===nk.SPREAD||e===nk.COLON||e===nk.EQUALS||e===nk.AT||e===nk.BRACKET_L||e===nk.BRACKET_R||e===nk.BRACE_L||e===nk.PIPE||e===nk.BRACE_R}function nL(e){return isNaN(e)?nk.EOF:e<127?JSON.stringify(String.fromCharCode(e)):'"\\u'.concat(("00"+e.toString(16).toUpperCase()).slice(-4),'"')}function nC(e,t){for(var n=e.source,r=n.body,i=r.length,a=t.end;a31||9===a))return new nS.WU(nk.COMMENT,t,s,n,r,i,o.slice(t+1,s))}function nN(e,t,n,r,i,a){var o=e.body,s=n,u=t,c=!1;if(45===s&&(s=o.charCodeAt(++u)),48===s){if((s=o.charCodeAt(++u))>=48&&s<=57)throw n_(e,u,"Invalid number, unexpected digit after 0: ".concat(nL(s),"."))}else u=nP(e,u,s),s=o.charCodeAt(u);if(46===s&&(c=!0,s=o.charCodeAt(++u),u=nP(e,u,s),s=o.charCodeAt(u)),(69===s||101===s)&&(c=!0,(43===(s=o.charCodeAt(++u))||45===s)&&(s=o.charCodeAt(++u)),u=nP(e,u,s),s=o.charCodeAt(u)),46===s||nU(s))throw n_(e,u,"Invalid number, expected digit but got: ".concat(nL(s),"."));return new nS.WU(c?nk.FLOAT:nk.INT,t,u,r,i,a,o.slice(t,u))}function nP(e,t,n){var r=e.body,i=t,a=n;if(a>=48&&a<=57){do a=r.charCodeAt(++i);while(a>=48&&a<=57)return i}throw n_(e,i,"Invalid number, expected digit but got: ".concat(nL(a),"."))}function nR(e,t,n,r,i){for(var a=e.body,o=t+1,s=o,u=0,c="";o=48&&e<=57?e-48:e>=65&&e<=70?e-55:e>=97&&e<=102?e-87:-1}function nB(e,t,n,r,i){for(var a=e.body,o=a.length,s=t+1,u=0;s!==o&&!isNaN(u=a.charCodeAt(s))&&(95===u||u>=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122);)++s;return new nS.WU(nk.NAME,t,s,n,r,i,a.slice(t,s))}function nU(e){return 95===e||e>=65&&e<=90||e>=97&&e<=122}function nH(e,t){return new n$(e,t).parseDocument()}var n$=function(){function e(e,t){var n=(0,nx.T)(e)?e:new nx.H(e);this._lexer=new nO(n),this._options=t}var t=e.prototype;return t.parseName=function(){var e=this.expectToken(nk.NAME);return{kind:nE.h.NAME,value:e.value,loc:this.loc(e)}},t.parseDocument=function(){var e=this._lexer.token;return{kind:nE.h.DOCUMENT,definitions:this.many(nk.SOF,this.parseDefinition,nk.EOF),loc:this.loc(e)}},t.parseDefinition=function(){if(this.peek(nk.NAME))switch(this._lexer.token.value){case"query":case"mutation":case"subscription":return this.parseOperationDefinition();case"fragment":return this.parseFragmentDefinition();case"schema":case"scalar":case"type":case"interface":case"union":case"enum":case"input":case"directive":return this.parseTypeSystemDefinition();case"extend":return this.parseTypeSystemExtension()}else if(this.peek(nk.BRACE_L))return this.parseOperationDefinition();else if(this.peekDescription())return this.parseTypeSystemDefinition();throw this.unexpected()},t.parseOperationDefinition=function(){var e,t=this._lexer.token;if(this.peek(nk.BRACE_L))return{kind:nE.h.OPERATION_DEFINITION,operation:"query",name:void 0,variableDefinitions:[],directives:[],selectionSet:this.parseSelectionSet(),loc:this.loc(t)};var n=this.parseOperationType();return this.peek(nk.NAME)&&(e=this.parseName()),{kind:nE.h.OPERATION_DEFINITION,operation:n,name:e,variableDefinitions:this.parseVariableDefinitions(),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseOperationType=function(){var e=this.expectToken(nk.NAME);switch(e.value){case"query":return"query";case"mutation":return"mutation";case"subscription":return"subscription"}throw this.unexpected(e)},t.parseVariableDefinitions=function(){return this.optionalMany(nk.PAREN_L,this.parseVariableDefinition,nk.PAREN_R)},t.parseVariableDefinition=function(){var e=this._lexer.token;return{kind:nE.h.VARIABLE_DEFINITION,variable:this.parseVariable(),type:(this.expectToken(nk.COLON),this.parseTypeReference()),defaultValue:this.expectOptionalToken(nk.EQUALS)?this.parseValueLiteral(!0):void 0,directives:this.parseDirectives(!0),loc:this.loc(e)}},t.parseVariable=function(){var e=this._lexer.token;return this.expectToken(nk.DOLLAR),{kind:nE.h.VARIABLE,name:this.parseName(),loc:this.loc(e)}},t.parseSelectionSet=function(){var e=this._lexer.token;return{kind:nE.h.SELECTION_SET,selections:this.many(nk.BRACE_L,this.parseSelection,nk.BRACE_R),loc:this.loc(e)}},t.parseSelection=function(){return this.peek(nk.SPREAD)?this.parseFragment():this.parseField()},t.parseField=function(){var e,t,n=this._lexer.token,r=this.parseName();return this.expectOptionalToken(nk.COLON)?(e=r,t=this.parseName()):t=r,{kind:nE.h.FIELD,alias:e,name:t,arguments:this.parseArguments(!1),directives:this.parseDirectives(!1),selectionSet:this.peek(nk.BRACE_L)?this.parseSelectionSet():void 0,loc:this.loc(n)}},t.parseArguments=function(e){var t=e?this.parseConstArgument:this.parseArgument;return this.optionalMany(nk.PAREN_L,t,nk.PAREN_R)},t.parseArgument=function(){var e=this._lexer.token,t=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.ARGUMENT,name:t,value:this.parseValueLiteral(!1),loc:this.loc(e)}},t.parseConstArgument=function(){var e=this._lexer.token;return{kind:nE.h.ARGUMENT,name:this.parseName(),value:(this.expectToken(nk.COLON),this.parseValueLiteral(!0)),loc:this.loc(e)}},t.parseFragment=function(){var e=this._lexer.token;this.expectToken(nk.SPREAD);var t=this.expectOptionalKeyword("on");return!t&&this.peek(nk.NAME)?{kind:nE.h.FRAGMENT_SPREAD,name:this.parseFragmentName(),directives:this.parseDirectives(!1),loc:this.loc(e)}:{kind:nE.h.INLINE_FRAGMENT,typeCondition:t?this.parseNamedType():void 0,directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseFragmentDefinition=function(){var e,t=this._lexer.token;return(this.expectKeyword("fragment"),(null===(e=this._options)||void 0===e?void 0:e.experimentalFragmentVariables)===!0)?{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),variableDefinitions:this.parseVariableDefinitions(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}:{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseFragmentName=function(){if("on"===this._lexer.token.value)throw this.unexpected();return this.parseName()},t.parseValueLiteral=function(e){var t=this._lexer.token;switch(t.kind){case nk.BRACKET_L:return this.parseList(e);case nk.BRACE_L:return this.parseObject(e);case nk.INT:return this._lexer.advance(),{kind:nE.h.INT,value:t.value,loc:this.loc(t)};case nk.FLOAT:return this._lexer.advance(),{kind:nE.h.FLOAT,value:t.value,loc:this.loc(t)};case nk.STRING:case nk.BLOCK_STRING:return this.parseStringLiteral();case nk.NAME:switch(this._lexer.advance(),t.value){case"true":return{kind:nE.h.BOOLEAN,value:!0,loc:this.loc(t)};case"false":return{kind:nE.h.BOOLEAN,value:!1,loc:this.loc(t)};case"null":return{kind:nE.h.NULL,loc:this.loc(t)};default:return{kind:nE.h.ENUM,value:t.value,loc:this.loc(t)}}case nk.DOLLAR:if(!e)return this.parseVariable()}throw this.unexpected()},t.parseStringLiteral=function(){var e=this._lexer.token;return this._lexer.advance(),{kind:nE.h.STRING,value:e.value,block:e.kind===nk.BLOCK_STRING,loc:this.loc(e)}},t.parseList=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseValueLiteral(e)};return{kind:nE.h.LIST,values:this.any(nk.BRACKET_L,r,nk.BRACKET_R),loc:this.loc(n)}},t.parseObject=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseObjectField(e)};return{kind:nE.h.OBJECT,fields:this.any(nk.BRACE_L,r,nk.BRACE_R),loc:this.loc(n)}},t.parseObjectField=function(e){var t=this._lexer.token,n=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.OBJECT_FIELD,name:n,value:this.parseValueLiteral(e),loc:this.loc(t)}},t.parseDirectives=function(e){for(var t=[];this.peek(nk.AT);)t.push(this.parseDirective(e));return t},t.parseDirective=function(e){var t=this._lexer.token;return this.expectToken(nk.AT),{kind:nE.h.DIRECTIVE,name:this.parseName(),arguments:this.parseArguments(e),loc:this.loc(t)}},t.parseTypeReference=function(){var e,t=this._lexer.token;return(this.expectOptionalToken(nk.BRACKET_L)?(e=this.parseTypeReference(),this.expectToken(nk.BRACKET_R),e={kind:nE.h.LIST_TYPE,type:e,loc:this.loc(t)}):e=this.parseNamedType(),this.expectOptionalToken(nk.BANG))?{kind:nE.h.NON_NULL_TYPE,type:e,loc:this.loc(t)}:e},t.parseNamedType=function(){var e=this._lexer.token;return{kind:nE.h.NAMED_TYPE,name:this.parseName(),loc:this.loc(e)}},t.parseTypeSystemDefinition=function(){var e=this.peekDescription()?this._lexer.lookahead():this._lexer.token;if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaDefinition();case"scalar":return this.parseScalarTypeDefinition();case"type":return this.parseObjectTypeDefinition();case"interface":return this.parseInterfaceTypeDefinition();case"union":return this.parseUnionTypeDefinition();case"enum":return this.parseEnumTypeDefinition();case"input":return this.parseInputObjectTypeDefinition();case"directive":return this.parseDirectiveDefinition()}throw this.unexpected(e)},t.peekDescription=function(){return this.peek(nk.STRING)||this.peek(nk.BLOCK_STRING)},t.parseDescription=function(){if(this.peekDescription())return this.parseStringLiteral()},t.parseSchemaDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("schema");var n=this.parseDirectives(!0),r=this.many(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);return{kind:nE.h.SCHEMA_DEFINITION,description:t,directives:n,operationTypes:r,loc:this.loc(e)}},t.parseOperationTypeDefinition=function(){var e=this._lexer.token,t=this.parseOperationType();this.expectToken(nk.COLON);var n=this.parseNamedType();return{kind:nE.h.OPERATION_TYPE_DEFINITION,operation:t,type:n,loc:this.loc(e)}},t.parseScalarTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("scalar");var n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.SCALAR_TYPE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("type");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.OBJECT_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseImplementsInterfaces=function(){var e;if(!this.expectOptionalKeyword("implements"))return[];if((null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLImplementsInterfaces)===!0){var t=[];this.expectOptionalToken(nk.AMP);do t.push(this.parseNamedType());while(this.expectOptionalToken(nk.AMP)||this.peek(nk.NAME))return t}return this.delimitedMany(nk.AMP,this.parseNamedType)},t.parseFieldsDefinition=function(){var e;return(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLEmptyFields)===!0&&this.peek(nk.BRACE_L)&&this._lexer.lookahead().kind===nk.BRACE_R?(this._lexer.advance(),this._lexer.advance(),[]):this.optionalMany(nk.BRACE_L,this.parseFieldDefinition,nk.BRACE_R)},t.parseFieldDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseArgumentDefs();this.expectToken(nk.COLON);var i=this.parseTypeReference(),a=this.parseDirectives(!0);return{kind:nE.h.FIELD_DEFINITION,description:t,name:n,arguments:r,type:i,directives:a,loc:this.loc(e)}},t.parseArgumentDefs=function(){return this.optionalMany(nk.PAREN_L,this.parseInputValueDef,nk.PAREN_R)},t.parseInputValueDef=function(){var e,t=this._lexer.token,n=this.parseDescription(),r=this.parseName();this.expectToken(nk.COLON);var i=this.parseTypeReference();this.expectOptionalToken(nk.EQUALS)&&(e=this.parseValueLiteral(!0));var a=this.parseDirectives(!0);return{kind:nE.h.INPUT_VALUE_DEFINITION,description:n,name:r,type:i,defaultValue:e,directives:a,loc:this.loc(t)}},t.parseInterfaceTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("interface");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.INTERFACE_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseUnionTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("union");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseUnionMemberTypes();return{kind:nE.h.UNION_TYPE_DEFINITION,description:t,name:n,directives:r,types:i,loc:this.loc(e)}},t.parseUnionMemberTypes=function(){return this.expectOptionalToken(nk.EQUALS)?this.delimitedMany(nk.PIPE,this.parseNamedType):[]},t.parseEnumTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("enum");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseEnumValuesDefinition();return{kind:nE.h.ENUM_TYPE_DEFINITION,description:t,name:n,directives:r,values:i,loc:this.loc(e)}},t.parseEnumValuesDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseEnumValueDefinition,nk.BRACE_R)},t.parseEnumValueDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.ENUM_VALUE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseInputObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("input");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseInputFieldsDefinition();return{kind:nE.h.INPUT_OBJECT_TYPE_DEFINITION,description:t,name:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInputFieldsDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseInputValueDef,nk.BRACE_R)},t.parseTypeSystemExtension=function(){var e=this._lexer.lookahead();if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaExtension();case"scalar":return this.parseScalarTypeExtension();case"type":return this.parseObjectTypeExtension();case"interface":return this.parseInterfaceTypeExtension();case"union":return this.parseUnionTypeExtension();case"enum":return this.parseEnumTypeExtension();case"input":return this.parseInputObjectTypeExtension()}throw this.unexpected(e)},t.parseSchemaExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("schema");var t=this.parseDirectives(!0),n=this.optionalMany(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);if(0===t.length&&0===n.length)throw this.unexpected();return{kind:nE.h.SCHEMA_EXTENSION,directives:t,operationTypes:n,loc:this.loc(e)}},t.parseScalarTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("scalar");var t=this.parseName(),n=this.parseDirectives(!0);if(0===n.length)throw this.unexpected();return{kind:nE.h.SCALAR_TYPE_EXTENSION,name:t,directives:n,loc:this.loc(e)}},t.parseObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("type");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.OBJECT_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInterfaceTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("interface");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.INTERFACE_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseUnionTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("union");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseUnionMemberTypes();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.UNION_TYPE_EXTENSION,name:t,directives:n,types:r,loc:this.loc(e)}},t.parseEnumTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("enum");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseEnumValuesDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.ENUM_TYPE_EXTENSION,name:t,directives:n,values:r,loc:this.loc(e)}},t.parseInputObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("input");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseInputFieldsDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.INPUT_OBJECT_TYPE_EXTENSION,name:t,directives:n,fields:r,loc:this.loc(e)}},t.parseDirectiveDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("directive"),this.expectToken(nk.AT);var n=this.parseName(),r=this.parseArgumentDefs(),i=this.expectOptionalKeyword("repeatable");this.expectKeyword("on");var a=this.parseDirectiveLocations();return{kind:nE.h.DIRECTIVE_DEFINITION,description:t,name:n,arguments:r,repeatable:i,locations:a,loc:this.loc(e)}},t.parseDirectiveLocations=function(){return this.delimitedMany(nk.PIPE,this.parseDirectiveLocation)},t.parseDirectiveLocation=function(){var e=this._lexer.token,t=this.parseName();if(void 0!==nT[t.value])return t;throw this.unexpected(e)},t.loc=function(e){var t;if((null===(t=this._options)||void 0===t?void 0:t.noLocation)!==!0)return new nS.Ye(e,this._lexer.lastToken,this._lexer.source)},t.peek=function(e){return this._lexer.token.kind===e},t.expectToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t;throw n_(this._lexer.source,t.start,"Expected ".concat(nG(e),", found ").concat(nz(t),"."))},t.expectOptionalToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t},t.expectKeyword=function(e){var t=this._lexer.token;if(t.kind===nk.NAME&&t.value===e)this._lexer.advance();else throw n_(this._lexer.source,t.start,'Expected "'.concat(e,'", found ').concat(nz(t),"."))},t.expectOptionalKeyword=function(e){var t=this._lexer.token;return t.kind===nk.NAME&&t.value===e&&(this._lexer.advance(),!0)},t.unexpected=function(e){var t=null!=e?e:this._lexer.token;return n_(this._lexer.source,t.start,"Unexpected ".concat(nz(t),"."))},t.any=function(e,t,n){this.expectToken(e);for(var r=[];!this.expectOptionalToken(n);)r.push(t.call(this));return r},t.optionalMany=function(e,t,n){if(this.expectOptionalToken(e)){var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r}return[]},t.many=function(e,t,n){this.expectToken(e);var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r},t.delimitedMany=function(e,t){this.expectOptionalToken(e);var n=[];do n.push(t.call(this));while(this.expectOptionalToken(e))return n},e}();function nz(e){var t=e.value;return nG(e.kind)+(null!=t?' "'.concat(t,'"'):"")}function nG(e){return nA(e)?'"'.concat(e,'"'):e}var nW=new Map,nK=new Map,nV=!0,nq=!1;function nZ(e){return e.replace(/[\s,]+/g," ").trim()}function nX(e){return nZ(e.source.body.substring(e.start,e.end))}function nJ(e){var t=new Set,n=[];return e.definitions.forEach(function(e){if("FragmentDefinition"===e.kind){var r=e.name.value,i=nX(e.loc),a=nK.get(r);a&&!a.has(i)?nV&&console.warn("Warning: fragment with name "+r+" already exists.\ngraphql-tag enforces all fragment names across your application to be unique; read more about\nthis in the docs: http://dev.apollodata.com/core/fragments.html#unique-names"):a||nK.set(r,a=new Set),a.add(i),t.has(i)||(t.add(i),n.push(e))}else n.push(e)}),(0,t0.pi)((0,t0.pi)({},e),{definitions:n})}function nQ(e){var t=new Set(e.definitions);t.forEach(function(e){e.loc&&delete e.loc,Object.keys(e).forEach(function(n){var r=e[n];r&&"object"==typeof r&&t.add(r)})});var n=e.loc;return n&&(delete n.startToken,delete n.endToken),e}function n1(e){var t=nZ(e);if(!nW.has(t)){var n=nH(e,{experimentalFragmentVariables:nq,allowLegacyFragmentVariables:nq});if(!n||"Document"!==n.kind)throw Error("Not a valid GraphQL document.");nW.set(t,nQ(nJ(n)))}return nW.get(t)}function n0(e){for(var t=[],n=1;n, or pass an ApolloClient instance in via options.'):(0,n7.kG)(!!n,32),n}var rb=n(10542),rm=n(53712),rg=n(21436),rv=Object.prototype.hasOwnProperty;function ry(e,t){return void 0===t&&(t=Object.create(null)),rw(rp(t.client),e).useQuery(t)}function rw(e,t){var n=(0,l.useRef)();n.current&&e===n.current.client&&t===n.current.query||(n.current=new r_(e,t,n.current));var r=n.current,i=(0,l.useState)(0),a=(i[0],i[1]);return r.forceUpdate=function(){a(function(e){return e+1})},r}var r_=function(){function e(e,t,n){this.client=e,this.query=t,this.ssrDisabledResult=(0,rb.J)({loading:!0,data:void 0,error:void 0,networkStatus:rc.I.loading}),this.skipStandbyResult=(0,rb.J)({loading:!1,data:void 0,error:void 0,networkStatus:rc.I.ready}),this.toQueryResultCache=new(re.mr?WeakMap:Map),rh(t,r.Query);var i=n&&n.result,a=i&&i.data;a&&(this.previousData=a)}return e.prototype.forceUpdate=function(){__DEV__&&n7.kG.warn("Calling default no-op implementation of InternalState#forceUpdate")},e.prototype.executeQuery=function(e){var t,n=this;e.query&&Object.assign(this,{query:e.query}),this.watchQueryOptions=this.createWatchQueryOptions(this.queryHookOptions=e);var r=this.observable.reobserveAsConcast(this.getObsQueryOptions());return this.previousData=(null===(t=this.result)||void 0===t?void 0:t.data)||this.previousData,this.result=void 0,this.forceUpdate(),new Promise(function(e){var t;r.subscribe({next:function(e){t=e},error:function(){e(n.toQueryResult(n.observable.getCurrentResult()))},complete:function(){e(n.toQueryResult(t))}})})},e.prototype.useQuery=function(e){var t=this;this.renderPromises=(0,l.useContext)((0,rs.K)()).renderPromises,this.useOptions(e);var n=this.useObservableQuery(),r=rn((0,l.useCallback)(function(){if(t.renderPromises)return function(){};var e=function(){var e=t.result,r=n.getCurrentResult();!(e&&e.loading===r.loading&&e.networkStatus===r.networkStatus&&(0,ra.D)(e.data,r.data))&&t.setResult(r)},r=function(a){var o=n.last;i.unsubscribe();try{n.resetLastResults(),i=n.subscribe(e,r)}finally{n.last=o}if(!rv.call(a,"graphQLErrors"))throw a;var s=t.result;(!s||s&&s.loading||!(0,ra.D)(a,s.error))&&t.setResult({data:s&&s.data,error:a,loading:!1,networkStatus:rc.I.error})},i=n.subscribe(e,r);return function(){return setTimeout(function(){return i.unsubscribe()})}},[n,this.renderPromises,this.client.disableNetworkFetches,]),function(){return t.getCurrentResult()},function(){return t.getCurrentResult()});return this.unsafeHandlePartialRefetch(r),this.toQueryResult(r)},e.prototype.useOptions=function(t){var n,r=this.createWatchQueryOptions(this.queryHookOptions=t),i=this.watchQueryOptions;!(0,ra.D)(r,i)&&(this.watchQueryOptions=r,i&&this.observable&&(this.observable.reobserve(this.getObsQueryOptions()),this.previousData=(null===(n=this.result)||void 0===n?void 0:n.data)||this.previousData,this.result=void 0)),this.onCompleted=t.onCompleted||e.prototype.onCompleted,this.onError=t.onError||e.prototype.onError,(this.renderPromises||this.client.disableNetworkFetches)&&!1===this.queryHookOptions.ssr&&!this.queryHookOptions.skip?this.result=this.ssrDisabledResult:this.queryHookOptions.skip||"standby"===this.watchQueryOptions.fetchPolicy?this.result=this.skipStandbyResult:(this.result===this.ssrDisabledResult||this.result===this.skipStandbyResult)&&(this.result=void 0)},e.prototype.getObsQueryOptions=function(){var e=[],t=this.client.defaultOptions.watchQuery;return t&&e.push(t),this.queryHookOptions.defaultOptions&&e.push(this.queryHookOptions.defaultOptions),e.push((0,rm.o)(this.observable&&this.observable.options,this.watchQueryOptions)),e.reduce(ro.J)},e.prototype.createWatchQueryOptions=function(e){void 0===e&&(e={});var t,n=e.skip,r=Object.assign((e.ssr,e.onCompleted,e.onError,e.defaultOptions,(0,n8._T)(e,["skip","ssr","onCompleted","onError","defaultOptions"])),{query:this.query});if(this.renderPromises&&("network-only"===r.fetchPolicy||"cache-and-network"===r.fetchPolicy)&&(r.fetchPolicy="cache-first"),r.variables||(r.variables={}),n){var i=r.fetchPolicy,a=void 0===i?this.getDefaultFetchPolicy():i,o=r.initialFetchPolicy;Object.assign(r,{initialFetchPolicy:void 0===o?a:o,fetchPolicy:"standby"})}else r.fetchPolicy||(r.fetchPolicy=(null===(t=this.observable)||void 0===t?void 0:t.options.initialFetchPolicy)||this.getDefaultFetchPolicy());return r},e.prototype.getDefaultFetchPolicy=function(){var e,t;return(null===(e=this.queryHookOptions.defaultOptions)||void 0===e?void 0:e.fetchPolicy)||(null===(t=this.client.defaultOptions.watchQuery)||void 0===t?void 0:t.fetchPolicy)||"cache-first"},e.prototype.onCompleted=function(e){},e.prototype.onError=function(e){},e.prototype.useObservableQuery=function(){var e=this.observable=this.renderPromises&&this.renderPromises.getSSRObservable(this.watchQueryOptions)||this.observable||this.client.watchQuery(this.getObsQueryOptions());this.obsQueryFields=(0,l.useMemo)(function(){return{refetch:e.refetch.bind(e),reobserve:e.reobserve.bind(e),fetchMore:e.fetchMore.bind(e),updateQuery:e.updateQuery.bind(e),startPolling:e.startPolling.bind(e),stopPolling:e.stopPolling.bind(e),subscribeToMore:e.subscribeToMore.bind(e)}},[e]);var t=!(!1===this.queryHookOptions.ssr||this.queryHookOptions.skip);return this.renderPromises&&t&&(this.renderPromises.registerSSRObservable(e),e.getCurrentResult().loading&&this.renderPromises.addObservableQueryPromise(e)),e},e.prototype.setResult=function(e){var t=this.result;t&&t.data&&(this.previousData=t.data),this.result=e,this.forceUpdate(),this.handleErrorOrCompleted(e)},e.prototype.handleErrorOrCompleted=function(e){var t=this;if(!e.loading){var n=this.toApolloError(e);Promise.resolve().then(function(){n?t.onError(n):e.data&&t.onCompleted(e.data)}).catch(function(e){__DEV__&&n7.kG.warn(e)})}},e.prototype.toApolloError=function(e){return(0,rg.O)(e.errors)?new ru.cA({graphQLErrors:e.errors}):e.error},e.prototype.getCurrentResult=function(){return this.result||this.handleErrorOrCompleted(this.result=this.observable.getCurrentResult()),this.result},e.prototype.toQueryResult=function(e){var t=this.toQueryResultCache.get(e);if(t)return t;var n=e.data,r=(e.partial,(0,n8._T)(e,["data","partial"]));return this.toQueryResultCache.set(e,t=(0,n8.pi)((0,n8.pi)((0,n8.pi)({data:n},r),this.obsQueryFields),{client:this.client,observable:this.observable,variables:this.observable.variables,called:!this.queryHookOptions.skip,previousData:this.previousData})),!t.error&&(0,rg.O)(e.errors)&&(t.error=new ru.cA({graphQLErrors:e.errors})),t},e.prototype.unsafeHandlePartialRefetch=function(e){e.partial&&this.queryHookOptions.partialRefetch&&!e.loading&&(!e.data||0===Object.keys(e.data).length)&&"cache-only"!==this.observable.options.fetchPolicy&&(Object.assign(e,{loading:!0,networkStatus:rc.I.refetch}),this.observable.refetch())},e}();function rE(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:{};return ry(i$,e)},iG=function(){var e=iF(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"50",10),r=iz({variables:{offset:(t-1)*n,limit:n},fetchPolicy:"network-only"}),i=r.data,a=r.loading,o=r.error;return a?l.createElement(ij,null):o?l.createElement(iN,{error:o}):i?l.createElement(iD,{chains:i.chains.results,page:t,pageSize:n,total:i.chains.metadata.total}):null},iW=n(67932),iK=n(8126),iV="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function iq(e){if(iZ())return Intl.DateTimeFormat.supportedLocalesOf(e)[0]}function iZ(){return("undefined"==typeof Intl?"undefined":iV(Intl))==="object"&&"function"==typeof Intl.DateTimeFormat}var iX="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},iJ=function(){function e(e,t){for(var n=0;n=i.length)break;s=i[o++]}else{if((o=i.next()).done)break;s=o.value}var s,u=s;if((void 0===e?"undefined":iX(e))!=="object")return;e=e[u]}return e}},{key:"put",value:function(){for(var e=arguments.length,t=Array(e),n=0;n=o.length)break;c=o[u++]}else{if((u=o.next()).done)break;c=u.value}var c,l=c;"object"!==iX(a[l])&&(a[l]={}),a=a[l]}return a[i]=r}}]),e}();let i0=i1;var i2=new i0;function i3(e,t){if(!iZ())return function(e){return e.toString()};var n=i5(e),r=JSON.stringify(t),i=i2.get(String(n),r)||i2.put(String(n),r,new Intl.DateTimeFormat(n,t));return function(e){return i.format(e)}}var i4={};function i5(e){var t=e.toString();return i4[t]?i4[t]:i4[t]=iq(e)}var i6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i9(e){return i8(e)?e:new Date(e)}function i8(e){return e instanceof Date||i7(e)}function i7(e){return(void 0===e?"undefined":i6(e))==="object"&&"function"==typeof e.getTime}var ae=n(54087),at=n.n(ae);function an(e,t){if(0===e.length)return 0;for(var n=0,r=e.length-1,i=void 0;n<=r;){var a=t(e[i=Math.floor((r+n)/2)]);if(0===a)return i;if(a<0){if((n=i+1)>r)return n}else if((r=i-1)=t.nextUpdateTime)ao(t,this.instances);else break}},scheduleNextTick:function(){var e=this;this.scheduledTick=at()(function(){e.tick(),e.scheduleNextTick()})},start:function(){this.scheduleNextTick()},stop:function(){at().cancel(this.scheduledTick)}};function aa(e){var t=ar(e.getNextValue(),2),n=t[0],r=t[1];e.setValue(n),e.nextUpdateTime=r}function ao(e,t){aa(e),au(t,e),as(t,e)}function as(e,t){var n=ac(e,t);e.splice(n,0,t)}function au(e,t){var n=e.indexOf(t);e.splice(n,1)}function ac(e,t){var n=t.nextUpdateTime;return an(e,function(e){return e.nextUpdateTime===n?0:e.nextUpdateTime>n?1:-1})}var al=(0,ec.oneOfType)([(0,ec.shape)({minTime:ec.number,formatAs:ec.string.isRequired}),(0,ec.shape)({test:ec.func,formatAs:ec.string.isRequired}),(0,ec.shape)({minTime:ec.number,format:ec.func.isRequired}),(0,ec.shape)({test:ec.func,format:ec.func.isRequired})]),af=(0,ec.oneOfType)([ec.string,(0,ec.shape)({steps:(0,ec.arrayOf)(al).isRequired,labels:(0,ec.oneOfType)([ec.string,(0,ec.arrayOf)(ec.string)]).isRequired,round:ec.string})]),ad=Object.assign||function(e){for(var t=1;t=0)&&Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function ab(e){var t=e.date,n=e.future,r=e.timeStyle,i=e.round,a=e.minTimeLeft,o=e.tooltip,s=e.component,u=e.container,c=e.wrapperComponent,f=e.wrapperProps,d=e.locale,h=e.locales,p=e.formatVerboseDate,b=e.verboseDateFormat,m=e.updateInterval,g=e.tick,v=ap(e,["date","future","timeStyle","round","minTimeLeft","tooltip","component","container","wrapperComponent","wrapperProps","locale","locales","formatVerboseDate","verboseDateFormat","updateInterval","tick"]),y=(0,l.useMemo)(function(){return d&&(h=[d]),h.concat(iK.Z.getDefaultLocale())},[d,h]),w=(0,l.useMemo)(function(){return new iK.Z(y)},[y]);t=(0,l.useMemo)(function(){return i9(t)},[t]);var _=(0,l.useCallback)(function(){var e=Date.now(),o=void 0;if(n&&e>=t.getTime()&&(e=t.getTime(),o=!0),void 0!==a){var s=t.getTime()-1e3*a;e>s&&(e=s,o=!0)}var u=w.format(t,r,{getTimeToNextUpdate:!0,now:e,future:n,round:i}),c=ah(u,2),l=c[0],f=c[1];return f=o?av:m||f||6e4,[l,e+f]},[t,n,r,m,i,a,w]),E=(0,l.useRef)();E.current=_;var S=(0,l.useMemo)(_,[]),k=ah(S,2),x=k[0],T=k[1],M=(0,l.useState)(x),O=ah(M,2),A=O[0],L=O[1],C=ah((0,l.useState)(),2),I=C[0],D=C[1],N=(0,l.useRef)();(0,l.useEffect)(function(){if(g)return N.current=ai.add({getNextValue:function(){return E.current()},setValue:L,nextUpdateTime:T}),function(){return N.current.stop()}},[g]),(0,l.useEffect)(function(){if(N.current)N.current.forceUpdate();else{var e=_(),t=ah(e,1)[0];L(t)}},[_]),(0,l.useEffect)(function(){D(!0)},[]);var P=(0,l.useMemo)(function(){if("undefined"!=typeof window)return i3(y,b)},[y,b]),R=(0,l.useMemo)(function(){if("undefined"!=typeof window)return p?p(t):P(t)},[t,p,P]),j=l.createElement(s,ad({date:t,verboseDate:I?R:void 0,tooltip:o},v),A),F=c||u;return F?l.createElement(F,ad({},f,{verboseDate:I?R:void 0}),j):j}ab.propTypes={date:el().oneOfType([el().instanceOf(Date),el().number]).isRequired,locale:el().string,locales:el().arrayOf(el().string),future:el().bool,timeStyle:af,round:el().string,minTimeLeft:el().number,component:el().elementType.isRequired,tooltip:el().bool.isRequired,formatVerboseDate:el().func,verboseDateFormat:el().object,updateInterval:el().oneOfType([el().number,el().arrayOf(el().shape({threshold:el().number,interval:el().number.isRequired}))]),tick:el().bool,wrapperComponent:el().func,wrapperProps:el().object},ab.defaultProps={locales:[],component:ay,tooltip:!0,verboseDateFormat:{weekday:"long",day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"},tick:!0},ab=l.memo(ab);let am=ab;var ag,av=31536e9;function ay(e){var t=e.date,n=e.verboseDate,r=e.tooltip,i=e.children,a=ap(e,["date","verboseDate","tooltip","children"]),o=(0,l.useMemo)(function(){return t.toISOString()},[t]);return l.createElement("time",ad({},a,{dateTime:o,title:r?n:void 0}),i)}ay.propTypes={date:el().instanceOf(Date).isRequired,verboseDate:el().string,tooltip:el().bool.isRequired,children:el().string.isRequired};var aw=n(30381),a_=n.n(aw),aE=n(31657);function aS(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ak(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?new ru.cA({graphQLErrors:i}):void 0;if(u===s.current.mutationId&&!c.ignoreResults){var f={called:!0,loading:!1,data:r,error:l,client:a};s.current.isMounted&&!(0,ra.D)(s.current.result,f)&&o(s.current.result=f)}var d=e.onCompleted||(null===(n=s.current.options)||void 0===n?void 0:n.onCompleted);return null==d||d(t.data,c),t}).catch(function(t){if(u===s.current.mutationId&&s.current.isMounted){var n,r={loading:!1,error:t,data:void 0,called:!0,client:a};(0,ra.D)(s.current.result,r)||o(s.current.result=r)}var i=e.onError||(null===(n=s.current.options)||void 0===n?void 0:n.onError);if(i)return i(t,c),{data:void 0,errors:t};throw t})},[]),c=(0,l.useCallback)(function(){s.current.isMounted&&o({called:!1,loading:!1,client:n})},[]);return(0,l.useEffect)(function(){return s.current.isMounted=!0,function(){s.current.isMounted=!1}},[]),[u,(0,n8.pi)({reset:c},a)]}var ou=n(59067),oc=n(28428),ol=n(11186),of=n(78513);function od(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var oh=function(e){return(0,b.createStyles)({paper:{display:"flex",margin:"".concat(2.5*e.spacing.unit,"px 0"),padding:"".concat(3*e.spacing.unit,"px ").concat(3.5*e.spacing.unit,"px")},content:{flex:1,width:"100%"},actions:od({marginTop:-(1.5*e.spacing.unit),marginLeft:-(4*e.spacing.unit)},e.breakpoints.up("sm"),{marginLeft:0,marginRight:-(1.5*e.spacing.unit)}),itemBlock:{border:"1px solid rgba(224, 224, 224, 1)",borderRadius:e.shape.borderRadius,padding:2*e.spacing.unit,marginTop:e.spacing.unit},itemBlockText:{overflowWrap:"anywhere"}})},op=(0,b.withStyles)(oh)(function(e){var t=e.actions,n=e.children,r=e.classes;return l.createElement(ia.default,{className:r.paper},l.createElement("div",{className:r.content},n),t&&l.createElement("div",{className:r.actions},t))}),ob=function(e){var t=e.title;return l.createElement(x.default,{variant:"subtitle2",gutterBottom:!0},t)},om=function(e){var t=e.children,n=e.value;return l.createElement(x.default,{variant:"body1",noWrap:!0},t||n)},og=(0,b.withStyles)(oh)(function(e){var t=e.children,n=e.classes,r=e.value;return l.createElement("div",{className:n.itemBlock},l.createElement(x.default,{variant:"body1",className:n.itemBlockText},t||r))});function ov(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]-1}let sZ=sq;function sX(e,t){var n=this.__data__,r=s$(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}let sJ=sX;function sQ(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=cI}let cN=cD;var cP="[object Arguments]",cR="[object Array]",cj="[object Boolean]",cF="[object Date]",cY="[object Error]",cB="[object Function]",cU="[object Map]",cH="[object Number]",c$="[object Object]",cz="[object RegExp]",cG="[object Set]",cW="[object String]",cK="[object WeakMap]",cV="[object ArrayBuffer]",cq="[object DataView]",cZ="[object Float64Array]",cX="[object Int8Array]",cJ="[object Int16Array]",cQ="[object Int32Array]",c1="[object Uint8Array]",c0="[object Uint8ClampedArray]",c2="[object Uint16Array]",c3="[object Uint32Array]",c4={};function c5(e){return eD(e)&&cN(e.length)&&!!c4[eC(e)]}c4["[object Float32Array]"]=c4[cZ]=c4[cX]=c4[cJ]=c4[cQ]=c4[c1]=c4[c0]=c4[c2]=c4[c3]=!0,c4[cP]=c4[cR]=c4[cV]=c4[cj]=c4[cq]=c4[cF]=c4[cY]=c4[cB]=c4[cU]=c4[cH]=c4[c$]=c4[cz]=c4[cG]=c4[cW]=c4[cK]=!1;let c6=c5;function c9(e){return function(t){return e(t)}}let c8=c9;var c7=n(79730),le=c7.Z&&c7.Z.isTypedArray,lt=le?c8(le):c6;let ln=lt;var lr=Object.prototype.hasOwnProperty;function li(e,t){var n=cT(e),r=!n&&ck(e),i=!n&&!r&&(0,cM.Z)(e),a=!n&&!r&&!i&&ln(e),o=n||r||i||a,s=o?cm(e.length,String):[],u=s.length;for(var c in e)(t||lr.call(e,c))&&!(o&&("length"==c||i&&("offset"==c||"parent"==c)||a&&("buffer"==c||"byteLength"==c||"byteOffset"==c)||cC(c,u)))&&s.push(c);return s}let la=li;var lo=Object.prototype;function ls(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||lo)}let lu=ls;var lc=sM(Object.keys,Object);let ll=lc;var lf=Object.prototype.hasOwnProperty;function ld(e){if(!lu(e))return ll(e);var t=[];for(var n in Object(e))lf.call(e,n)&&"constructor"!=n&&t.push(n);return t}let lh=ld;function lp(e){return null!=e&&cN(e.length)&&!ui(e)}let lb=lp;function lm(e){return lb(e)?la(e):lh(e)}let lg=lm;function lv(e,t){return e&&cp(t,lg(t),e)}let ly=lv;function lw(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}let l_=lw;var lE=Object.prototype.hasOwnProperty;function lS(e){if(!ed(e))return l_(e);var t=lu(e),n=[];for(var r in e)"constructor"==r&&(t||!lE.call(e,r))||n.push(r);return n}let lk=lS;function lx(e){return lb(e)?la(e,!0):lk(e)}let lT=lx;function lM(e,t){return e&&cp(t,lT(t),e)}let lO=lM;var lA=n(42896);function lL(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n=0||(i[n]=e[n]);return i}function hc(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var hl=function(e){return Array.isArray(e)&&0===e.length},hf=function(e){return"function"==typeof e},hd=function(e){return null!==e&&"object"==typeof e},hh=function(e){return String(Math.floor(Number(e)))===e},hp=function(e){return"[object String]"===Object.prototype.toString.call(e)},hb=function(e){return 0===l.Children.count(e)},hm=function(e){return hd(e)&&hf(e.then)};function hg(e,t,n,r){void 0===r&&(r=0);for(var i=d8(t);e&&r=0?[]:{}}}return(0===a?e:i)[o[a]]===n?e:(void 0===n?delete i[o[a]]:i[o[a]]=n,0===a&&void 0===n&&delete r[o[a]],r)}function hy(e,t,n,r){void 0===n&&(n=new WeakMap),void 0===r&&(r={});for(var i=0,a=Object.keys(e);i0?t.map(function(t){return x(t,hg(e,t))}):[Promise.resolve("DO_NOT_DELETE_YOU_WILL_BE_FIRED")]).then(function(e){return e.reduce(function(e,n,r){return"DO_NOT_DELETE_YOU_WILL_BE_FIRED"===n||n&&(e=hv(e,t[r],n)),e},{})})},[x]),M=(0,l.useCallback)(function(e){return Promise.all([T(e),h.validationSchema?k(e):{},h.validate?S(e):{}]).then(function(e){var t=e[0],n=e[1],r=e[2];return sx.all([t,n,r],{arrayMerge:hC})})},[h.validate,h.validationSchema,T,S,k]),O=hP(function(e){return void 0===e&&(e=_.values),E({type:"SET_ISVALIDATING",payload:!0}),M(e).then(function(e){return v.current&&(E({type:"SET_ISVALIDATING",payload:!1}),sh()(_.errors,e)||E({type:"SET_ERRORS",payload:e})),e})});(0,l.useEffect)(function(){o&&!0===v.current&&sh()(p.current,h.initialValues)&&O(p.current)},[o,O]);var A=(0,l.useCallback)(function(e){var t=e&&e.values?e.values:p.current,n=e&&e.errors?e.errors:b.current?b.current:h.initialErrors||{},r=e&&e.touched?e.touched:m.current?m.current:h.initialTouched||{},i=e&&e.status?e.status:g.current?g.current:h.initialStatus;p.current=t,b.current=n,m.current=r,g.current=i;var a=function(){E({type:"RESET_FORM",payload:{isSubmitting:!!e&&!!e.isSubmitting,errors:n,touched:r,status:i,values:t,isValidating:!!e&&!!e.isValidating,submitCount:e&&e.submitCount&&"number"==typeof e.submitCount?e.submitCount:0}})};if(h.onReset){var o=h.onReset(_.values,V);hm(o)?o.then(a):a()}else a()},[h.initialErrors,h.initialStatus,h.initialTouched]);(0,l.useEffect)(function(){!0===v.current&&!sh()(p.current,h.initialValues)&&(c&&(p.current=h.initialValues,A()),o&&O(p.current))},[c,h.initialValues,A,o,O]),(0,l.useEffect)(function(){c&&!0===v.current&&!sh()(b.current,h.initialErrors)&&(b.current=h.initialErrors||hk,E({type:"SET_ERRORS",payload:h.initialErrors||hk}))},[c,h.initialErrors]),(0,l.useEffect)(function(){c&&!0===v.current&&!sh()(m.current,h.initialTouched)&&(m.current=h.initialTouched||hx,E({type:"SET_TOUCHED",payload:h.initialTouched||hx}))},[c,h.initialTouched]),(0,l.useEffect)(function(){c&&!0===v.current&&!sh()(g.current,h.initialStatus)&&(g.current=h.initialStatus,E({type:"SET_STATUS",payload:h.initialStatus}))},[c,h.initialStatus,h.initialTouched]);var L=hP(function(e){if(y.current[e]&&hf(y.current[e].validate)){var t=hg(_.values,e),n=y.current[e].validate(t);return hm(n)?(E({type:"SET_ISVALIDATING",payload:!0}),n.then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}}),E({type:"SET_ISVALIDATING",payload:!1})})):(E({type:"SET_FIELD_ERROR",payload:{field:e,value:n}}),Promise.resolve(n))}return h.validationSchema?(E({type:"SET_ISVALIDATING",payload:!0}),k(_.values,e).then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t[e]}}),E({type:"SET_ISVALIDATING",payload:!1})})):Promise.resolve()}),C=(0,l.useCallback)(function(e,t){var n=t.validate;y.current[e]={validate:n}},[]),I=(0,l.useCallback)(function(e){delete y.current[e]},[]),D=hP(function(e,t){return E({type:"SET_TOUCHED",payload:e}),(void 0===t?i:t)?O(_.values):Promise.resolve()}),N=(0,l.useCallback)(function(e){E({type:"SET_ERRORS",payload:e})},[]),P=hP(function(e,t){var r=hf(e)?e(_.values):e;return E({type:"SET_VALUES",payload:r}),(void 0===t?n:t)?O(r):Promise.resolve()}),R=(0,l.useCallback)(function(e,t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}})},[]),j=hP(function(e,t,r){return E({type:"SET_FIELD_VALUE",payload:{field:e,value:t}}),(void 0===r?n:r)?O(hv(_.values,e,t)):Promise.resolve()}),F=(0,l.useCallback)(function(e,t){var n,r=t,i=e;if(!hp(e)){e.persist&&e.persist();var a=e.target?e.target:e.currentTarget,o=a.type,s=a.name,u=a.id,c=a.value,l=a.checked,f=(a.outerHTML,a.options),d=a.multiple;r=t||s||u,i=/number|range/.test(o)?(n=parseFloat(c),isNaN(n)?"":n):/checkbox/.test(o)?hD(hg(_.values,r),l,c):d?hI(f):c}r&&j(r,i)},[j,_.values]),Y=hP(function(e){if(hp(e))return function(t){return F(t,e)};F(e)}),B=hP(function(e,t,n){return void 0===t&&(t=!0),E({type:"SET_FIELD_TOUCHED",payload:{field:e,value:t}}),(void 0===n?i:n)?O(_.values):Promise.resolve()}),U=(0,l.useCallback)(function(e,t){e.persist&&e.persist();var n,r=e.target,i=r.name,a=r.id;r.outerHTML,B(t||i||a,!0)},[B]),H=hP(function(e){if(hp(e))return function(t){return U(t,e)};U(e)}),$=(0,l.useCallback)(function(e){hf(e)?E({type:"SET_FORMIK_STATE",payload:e}):E({type:"SET_FORMIK_STATE",payload:function(){return e}})},[]),z=(0,l.useCallback)(function(e){E({type:"SET_STATUS",payload:e})},[]),G=(0,l.useCallback)(function(e){E({type:"SET_ISSUBMITTING",payload:e})},[]),W=hP(function(){return E({type:"SUBMIT_ATTEMPT"}),O().then(function(e){var t,n=e instanceof Error;if(!n&&0===Object.keys(e).length){try{if(void 0===(t=q()))return}catch(r){throw r}return Promise.resolve(t).then(function(e){return v.current&&E({type:"SUBMIT_SUCCESS"}),e}).catch(function(e){if(v.current)throw E({type:"SUBMIT_FAILURE"}),e})}if(v.current&&(E({type:"SUBMIT_FAILURE"}),n))throw e})}),K=hP(function(e){e&&e.preventDefault&&hf(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hf(e.stopPropagation)&&e.stopPropagation(),W().catch(function(e){console.warn("Warning: An unhandled error was caught from submitForm()",e)})}),V={resetForm:A,validateForm:O,validateField:L,setErrors:N,setFieldError:R,setFieldTouched:B,setFieldValue:j,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,setFormikState:$,submitForm:W},q=hP(function(){return f(_.values,V)}),Z=hP(function(e){e&&e.preventDefault&&hf(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hf(e.stopPropagation)&&e.stopPropagation(),A()}),X=(0,l.useCallback)(function(e){return{value:hg(_.values,e),error:hg(_.errors,e),touched:!!hg(_.touched,e),initialValue:hg(p.current,e),initialTouched:!!hg(m.current,e),initialError:hg(b.current,e)}},[_.errors,_.touched,_.values]),J=(0,l.useCallback)(function(e){return{setValue:function(t,n){return j(e,t,n)},setTouched:function(t,n){return B(e,t,n)},setError:function(t){return R(e,t)}}},[j,B,R]),Q=(0,l.useCallback)(function(e){var t=hd(e),n=t?e.name:e,r=hg(_.values,n),i={name:n,value:r,onChange:Y,onBlur:H};if(t){var a=e.type,o=e.value,s=e.as,u=e.multiple;"checkbox"===a?void 0===o?i.checked=!!r:(i.checked=!!(Array.isArray(r)&&~r.indexOf(o)),i.value=o):"radio"===a?(i.checked=r===o,i.value=o):"select"===s&&u&&(i.value=i.value||[],i.multiple=!0)}return i},[H,Y,_.values]),ee=(0,l.useMemo)(function(){return!sh()(p.current,_.values)},[p.current,_.values]),et=(0,l.useMemo)(function(){return void 0!==s?ee?_.errors&&0===Object.keys(_.errors).length:!1!==s&&hf(s)?s(h):s:_.errors&&0===Object.keys(_.errors).length},[s,ee,_.errors,h]);return ho({},_,{initialValues:p.current,initialErrors:b.current,initialTouched:m.current,initialStatus:g.current,handleBlur:H,handleChange:Y,handleReset:Z,handleSubmit:K,resetForm:A,setErrors:N,setFormikState:$,setFieldTouched:B,setFieldValue:j,setFieldError:R,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,submitForm:W,validateForm:O,validateField:L,isValid:et,dirty:ee,unregisterField:I,registerField:C,getFieldProps:Q,getFieldMeta:X,getFieldHelpers:J,validateOnBlur:i,validateOnChange:n,validateOnMount:o})}function hM(e){var t=hT(e),n=e.component,r=e.children,i=e.render,a=e.innerRef;return(0,l.useImperativeHandle)(a,function(){return t}),(0,l.createElement)(h_,{value:t},n?(0,l.createElement)(n,t):i?i(t):r?hf(r)?r(t):hb(r)?null:l.Children.only(r):null)}function hO(e){var t={};if(e.inner){if(0===e.inner.length)return hv(t,e.path,e.message);for(var n=e.inner,r=Array.isArray(n),i=0,n=r?n:n[Symbol.iterator]();;){if(r){if(i>=n.length)break;a=n[i++]}else{if((i=n.next()).done)break;a=i.value}var a,o=a;hg(t,o.path)||(t=hv(t,o.path,o.message))}}return t}function hA(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r={});var i=hL(e);return t[n?"validateSync":"validate"](i,{abortEarly:!1,context:r})}function hL(e){var t=Array.isArray(e)?[]:{};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=String(n);!0===Array.isArray(e[r])?t[r]=e[r].map(function(e){return!0===Array.isArray(e)||sj(e)?hL(e):""!==e?e:void 0}):sj(e[r])?t[r]=hL(e[r]):t[r]=""!==e[r]?e[r]:void 0}return t}function hC(e,t,n){var r=e.slice();return t.forEach(function(t,i){if(void 0===r[i]){var a=!1!==n.clone&&n.isMergeableObject(t);r[i]=a?sx(Array.isArray(t)?[]:{},t,n):t}else n.isMergeableObject(t)?r[i]=sx(e[i],t,n):-1===e.indexOf(t)&&r.push(t)}),r}function hI(e){return Array.from(e).filter(function(e){return e.selected}).map(function(e){return e.value})}function hD(e,t,n){if("boolean"==typeof e)return Boolean(t);var r=[],i=!1,a=-1;if(Array.isArray(e))r=e,i=(a=e.indexOf(n))>=0;else if(!n||"true"==n||"false"==n)return Boolean(t);return t&&n&&!i?r.concat(n):i?r.slice(0,a).concat(r.slice(a+1)):r}var hN="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?l.useLayoutEffect:l.useEffect;function hP(e){var t=(0,l.useRef)(e);return hN(function(){t.current=e}),(0,l.useCallback)(function(){for(var e=arguments.length,n=Array(e),r=0;re?t:e},0);return Array.from(ho({},e,{length:t+1}))};(function(e){function t(t){var n;return(n=e.call(this,t)||this).updateArrayField=function(e,t,r){var i=n.props,a=i.name;(0,i.formik.setFormikState)(function(n){var i="function"==typeof r?r:e,o="function"==typeof t?t:e,s=hv(n.values,a,e(hg(n.values,a))),u=r?i(hg(n.errors,a)):void 0,c=t?o(hg(n.touched,a)):void 0;return hl(u)&&(u=void 0),hl(c)&&(c=void 0),ho({},n,{values:s,errors:r?hv(n.errors,a,u):n.errors,touched:t?hv(n.touched,a,c):n.touched})})},n.push=function(e){return n.updateArrayField(function(t){return[].concat(hH(t),[ha(e)])},!1,!1)},n.handlePush=function(e){return function(){return n.push(e)}},n.swap=function(e,t){return n.updateArrayField(function(n){return hY(n,e,t)},!0,!0)},n.handleSwap=function(e,t){return function(){return n.swap(e,t)}},n.move=function(e,t){return n.updateArrayField(function(n){return hF(n,e,t)},!0,!0)},n.handleMove=function(e,t){return function(){return n.move(e,t)}},n.insert=function(e,t){return n.updateArrayField(function(n){return hB(n,e,t)},function(t){return hB(t,e,null)},function(t){return hB(t,e,null)})},n.handleInsert=function(e,t){return function(){return n.insert(e,t)}},n.replace=function(e,t){return n.updateArrayField(function(n){return hU(n,e,t)},!1,!1)},n.handleReplace=function(e,t){return function(){return n.replace(e,t)}},n.unshift=function(e){var t=-1;return n.updateArrayField(function(n){var r=n?[e].concat(n):[e];return t<0&&(t=r.length),r},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n}),t},n.handleUnshift=function(e){return function(){return n.unshift(e)}},n.handleRemove=function(e){return function(){return n.remove(e)}},n.handlePop=function(){return function(){return n.pop()}},n.remove=n.remove.bind(hc(n)),n.pop=n.pop.bind(hc(n)),n}hs(t,e);var n=t.prototype;return n.componentDidUpdate=function(e){this.props.validateOnChange&&this.props.formik.validateOnChange&&!sh()(hg(e.formik.values,e.name),hg(this.props.formik.values,this.props.name))&&this.props.formik.validateForm(this.props.formik.values)},n.remove=function(e){var t;return this.updateArrayField(function(n){var r=n?hH(n):[];return t||(t=r[e]),hf(r.splice)&&r.splice(e,1),r},!0,!0),t},n.pop=function(){var e;return this.updateArrayField(function(t){var n=t;return e||(e=n&&n.pop&&n.pop()),n},!0,!0),e},n.render=function(){var e={push:this.push,pop:this.pop,swap:this.swap,move:this.move,insert:this.insert,replace:this.replace,unshift:this.unshift,remove:this.remove,handlePush:this.handlePush,handlePop:this.handlePop,handleSwap:this.handleSwap,handleMove:this.handleMove,handleInsert:this.handleInsert,handleReplace:this.handleReplace,handleUnshift:this.handleUnshift,handleRemove:this.handleRemove},t=this.props,n=t.component,r=t.render,i=t.children,a=t.name,o=hu(t.formik,["validate","validationSchema"]),s=ho({},e,{form:o,name:a});return n?(0,l.createElement)(n,s):r?r(s):i?"function"==typeof i?i(s):hb(i)?null:l.Children.only(i):null},t})(l.Component).defaultProps={validateOnChange:!0},l.Component,l.Component;var h$=n(24802),hz=n(71209),hG=n(91750),hW=n(11970),hK=n(4689),hV=n(67598),hq=function(){return(hq=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&(n[r[i]]=e[r[i]]);return n}function hX(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hZ(n,["onBlur"]),a=e.form,o=a.isSubmitting,s=a.touched,u=a.errors,c=e.onBlur,l=e.helperText,f=hZ(e,["disabled","field","form","onBlur","helperText"]),d=hg(u,i.name),h=hg(s,i.name)&&!!d;return hq(hq({variant:f.variant,error:h,helperText:h?d:l,disabled:null!=t?t:o,onBlur:null!=c?c:function(e){r(null!=e?e:i.name)}},i),f)}function hJ(e){var t=e.children,n=hZ(e,["children"]);return(0,l.createElement)(i_.Z,hq({},hX(n)),t)}function hQ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hZ(n,["onBlur"]),a=e.form.isSubmitting,o=(e.type,e.onBlur),s=hZ(e,["disabled","field","form","type","onBlur"]);return hq(hq({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h1(e){return(0,l.createElement)(h$.Z,hq({},hQ(e)))}function h0(e){var t,n=e.disabled,r=e.field,i=r.onBlur,a=hZ(r,["onBlur"]),o=e.form.isSubmitting,s=(e.type,e.onBlur),u=hZ(e,["disabled","field","form","type","onBlur"]);return hq(hq({disabled:null!=n?n:o,indeterminate:!Array.isArray(a.value)&&null==a.value,onBlur:null!=s?s:function(e){i(null!=e?e:a.name)}},a),u)}function h2(e){return(0,l.createElement)(hz.Z,hq({},h0(e)))}function h3(e){var t=e.Label,n=hZ(e,["Label"]);return(0,l.createElement)(hG.Z,hq({control:(0,l.createElement)(hz.Z,hq({},h0(n)))},t))}function h4(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hZ(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hZ(e,["disabled","field","form","onBlur"]);return hq(hq({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h5(e){return(0,l.createElement)(hW.default,hq({},h4(e)))}function h6(e){var t=e.field,n=t.onBlur,r=hZ(t,["onBlur"]),i=(e.form,e.onBlur),a=hZ(e,["field","form","onBlur"]);return hq(hq({onBlur:null!=i?i:function(e){n(null!=e?e:r.name)}},r),a)}function h9(e){return(0,l.createElement)(hK.Z,hq({},h6(e)))}function h8(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hZ(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hZ(e,["disabled","field","form","onBlur"]);return hq(hq({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h7(e){return(0,l.createElement)(hV.default,hq({},h8(e)))}hJ.displayName="FormikMaterialUITextField",h1.displayName="FormikMaterialUISwitch",h2.displayName="FormikMaterialUICheckbox",h3.displayName="FormikMaterialUICheckboxWithLabel",h5.displayName="FormikMaterialUISelect",h9.displayName="FormikMaterialUIRadioGroup",h7.displayName="FormikMaterialUIInputBase";try{a=Map}catch(pe){}try{o=Set}catch(pt){}function pn(e,t,n){if(!e||"object"!=typeof e||"function"==typeof e)return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return RegExp(e);if(Array.isArray(e))return e.map(pr);if(a&&e instanceof a)return new Map(Array.from(e.entries()));if(o&&e instanceof o)return new Set(Array.from(e.values()));if(e instanceof Object){t.push(e);var r=Object.create(e);for(var i in n.push(r),e){var s=t.findIndex(function(t){return t===e[i]});r[i]=s>-1?n[s]:pn(e[i],t,n)}return r}return e}function pr(e){return pn(e,[],[])}let pi=Object.prototype.toString,pa=Error.prototype.toString,po=RegExp.prototype.toString,ps="undefined"!=typeof Symbol?Symbol.prototype.toString:()=>"",pu=/^Symbol\((.*)\)(.*)$/;function pc(e){if(e!=+e)return"NaN";let t=0===e&&1/e<0;return t?"-0":""+e}function pl(e,t=!1){if(null==e||!0===e||!1===e)return""+e;let n=typeof e;if("number"===n)return pc(e);if("string"===n)return t?`"${e}"`:e;if("function"===n)return"[Function "+(e.name||"anonymous")+"]";if("symbol"===n)return ps.call(e).replace(pu,"Symbol($1)");let r=pi.call(e).slice(8,-1);return"Date"===r?isNaN(e.getTime())?""+e:e.toISOString(e):"Error"===r||e instanceof Error?"["+pa.call(e)+"]":"RegExp"===r?po.call(e):null}function pf(e,t){let n=pl(e,t);return null!==n?n:JSON.stringify(e,function(e,n){let r=pl(this[e],t);return null!==r?r:n},2)}let pd={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType({path:e,type:t,value:n,originalValue:r}){let i=null!=r&&r!==n,a=`${e} must be a \`${t}\` type, but the final value was: \`${pf(n,!0)}\``+(i?` (cast from the value \`${pf(r,!0)}\`).`:".");return null===n&&(a+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),a},defined:"${path} must be defined"},ph={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"},pp={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"},pb={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"},pm={isValue:"${path} field must be ${value}"},pg={noUnknown:"${path} field has unspecified keys: ${unknown}"},pv={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};Object.assign(Object.create(null),{mixed:pd,string:ph,number:pp,date:pb,object:pg,array:pv,boolean:pm});var py=n(18721),pw=n.n(py);let p_=e=>e&&e.__isYupSchema__;class pE{constructor(e,t){if(this.refs=e,this.refs=e,"function"==typeof t){this.fn=t;return}if(!pw()(t,"is"))throw TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:n,then:r,otherwise:i}=t,a="function"==typeof n?n:(...e)=>e.every(e=>e===n);this.fn=function(...e){let t=e.pop(),n=e.pop(),o=a(...e)?r:i;if(o)return"function"==typeof o?o(n):n.concat(o.resolve(t))}}resolve(e,t){let n=this.refs.map(e=>e.getValue(null==t?void 0:t.value,null==t?void 0:t.parent,null==t?void 0:t.context)),r=this.fn.apply(e,n.concat(e,t));if(void 0===r||r===e)return e;if(!p_(r))throw TypeError("conditions must return a schema object");return r.resolve(t)}}let pS=pE;function pk(e){return null==e?[]:[].concat(e)}function px(){return(px=Object.assign||function(e){for(var t=1;tpf(t[n])):"function"==typeof e?e(t):e}static isError(e){return e&&"ValidationError"===e.name}constructor(e,t,n,r){super(),this.name="ValidationError",this.value=t,this.path=n,this.type=r,this.errors=[],this.inner=[],pk(e).forEach(e=>{pM.isError(e)?(this.errors.push(...e.errors),this.inner=this.inner.concat(e.inner.length?e.inner:e)):this.errors.push(e)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,pM)}}let pO=e=>{let t=!1;return(...n)=>{t||(t=!0,e(...n))}};function pA(e,t){let{endEarly:n,tests:r,args:i,value:a,errors:o,sort:s,path:u}=e,c=pO(t),l=r.length,f=[];if(o=o||[],!l)return o.length?c(new pM(o,a,u)):c(null,a);for(let d=0;d=0||(i[n]=e[n]);return i}function pj(e){function t(t,n){let{value:r,path:i="",label:a,options:o,originalValue:s,sync:u}=t,c=pR(t,["value","path","label","options","originalValue","sync"]),{name:l,test:f,params:d,message:h}=e,{parent:p,context:b}=o;function m(e){return pN.isRef(e)?e.getValue(r,p,b):e}function g(e={}){let t=pC()(pP({value:r,originalValue:s,label:a,path:e.path||i},d,e.params),m),n=new pM(pM.formatError(e.message||h,t),r,t.path,e.type||l);return n.params=t,n}let v=pP({path:i,parent:p,type:l,createError:g,resolve:m,options:o,originalValue:s},c);if(!u){try{Promise.resolve(f.call(v,r,v)).then(e=>{pM.isError(e)?n(e):e?n(null,e):n(g())})}catch(y){n(y)}return}let w;try{var _;if(w=f.call(v,r,v),"function"==typeof(null==(_=w)?void 0:_.then))throw Error(`Validation test of type: "${v.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(E){n(E);return}pM.isError(w)?n(w):w?n(null,w):n(g())}return t.OPTIONS=e,t}pN.prototype.__isYupRef=!0;let pF=e=>e.substr(0,e.length-1).substr(1);function pY(e,t,n,r=n){let i,a,o;return t?((0,pI.forEach)(t,(s,u,c)=>{let l=u?pF(s):s;if((e=e.resolve({context:r,parent:i,value:n})).innerType){let f=c?parseInt(l,10):0;if(n&&f>=n.length)throw Error(`Yup.reach cannot resolve an array item at index: ${s}, in the path: ${t}. because there is no value at that index. `);i=n,n=n&&n[f],e=e.innerType}if(!c){if(!e.fields||!e.fields[l])throw Error(`The schema does not contain the path: ${t}. (failed at: ${o} which is a type: "${e._type}")`);i=n,n=n&&n[l],e=e.fields[l]}a=l,o=u?"["+s+"]":"."+s}),{schema:e,parent:i,parentPath:a}):{parent:i,parentPath:t,schema:e}}class pB{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,n]of this.refs)e.push(n.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){pN.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){pN.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let n,r=this.refs.values();for(;!(n=r.next()).done;)if(t(n.value)===e)return!0;return!1}clone(){let e=new pB;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let n=this.clone();return e.list.forEach(e=>n.add(e)),e.refs.forEach(e=>n.add(e)),t.list.forEach(e=>n.delete(e)),t.refs.forEach(e=>n.delete(e)),n}}function pU(){return(pU=Object.assign||function(e){for(var t=1;t{this.typeError(pd.notType)}),this.type=(null==e?void 0:e.type)||"mixed",this.spec=pU({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},null==e?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=pU({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=pr(pU({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(0===e.length)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let n=e(this);return this._mutate=t,n}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&"mixed"!==this.type)throw TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,n=e.clone(),r=pU({},t.spec,n.spec);return n.spec=r,n._typeError||(n._typeError=t._typeError),n._whitelistError||(n._whitelistError=t._whitelistError),n._blacklistError||(n._blacklistError=t._blacklistError),n._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),n._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),n.tests=t.tests,n.exclusiveTests=t.exclusiveTests,n.withMutation(t=>{e.tests.forEach(e=>{t.test(e.OPTIONS)})}),n}isType(e){return!!this.spec.nullable&&null===e||this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let n=t.conditions;(t=t.clone()).conditions=[],t=(t=n.reduce((t,n)=>n.resolve(t,e),t)).resolve(e)}return t}cast(e,t={}){let n=this.resolve(pU({value:e},t)),r=n._cast(e,t);if(void 0!==e&&!1!==t.assert&&!0!==n.isType(r)){let i=pf(e),a=pf(r);throw TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${n._type}".
attempted value: ${i}
-`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pU({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pA({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pA({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pU({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pU({},t,{value:e}))._validate(e,pU({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pM.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pM.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pr(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pd.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pd.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pd.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pj(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pk(e).map(e=>new pN(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pS(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pj({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pd.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pj({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pd.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pj({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let p$ of(pH.prototype.__isYupSchema__=!0,["validate","validateSync"]))pH.prototype[`${p$}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pY(this,e,t,n.context);return a[p$](r&&r[i],pU({},n,{parent:r,path:e}))};for(let pz of["equals","is"])pH.prototype[pz]=pH.prototype.oneOf;for(let pG of["not","nope"])pH.prototype[pG]=pH.prototype.notOneOf;pH.prototype.optional=pH.prototype.notRequired;let pW=pH;function pK(){return new pW}pK.prototype=pW.prototype;let pV=e=>null==e;function pq(){return new pZ}class pZ extends pH{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pm.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pV(e)||!0===e})}isFalse(e=pm.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pV(e)||!1===e})}}pq.prototype=pZ.prototype;let pX=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pJ=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pQ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,p1=e=>pV(e)||e===e.trim(),p0=({}).toString();function p2(){return new p3}class p3 extends pH{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p0?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=ph.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pV(t)||t.length===this.resolve(e)}})}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t.length>=this.resolve(e)}})}max(e,t=ph.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pV(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||ph.matches,params:{regex:e},test:t=>pV(t)||""===t&&n||-1!==t.search(e)})}email(e=ph.email){return this.matches(pX,{name:"email",message:e,excludeEmptyString:!0})}url(e=ph.url){return this.matches(pJ,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=ph.uuid){return this.matches(pQ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=ph.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:p1})}lowercase(e=ph.lowercase){return this.transform(e=>pV(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pV(e)||e===e.toLowerCase()})}uppercase(e=ph.uppercase){return this.transform(e=>pV(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pV(e)||e===e.toUpperCase()})}}p2.prototype=p3.prototype;let p4=e=>e!=+e;function p5(){return new p6}class p6 extends pH{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p4(e)}min(e,t=pp.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t>=this.resolve(e)}})}max(e,t=pp.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pV(t)||t<=this.resolve(e)}})}lessThan(e,t=pp.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pV(t)||tthis.resolve(e)}})}positive(e=pp.positive){return this.moreThan(0,e)}negative(e=pp.negative){return this.lessThan(0,e)}integer(e=pp.integer){return this.test({name:"integer",message:e,test:e=>pV(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pV(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pV(t)?t:Math[e](t))}}p5.prototype=p6.prototype;var p9=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p9.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p7=new Date(""),be=e=>"[object Date]"===Object.prototype.toString.call(e);function bt(){return new bn}class bn extends pH{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p7:new Date(e))})})}_typeCheck(e){return be(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pN.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pb.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pV(e)||e>=this.resolve(n)}})}max(e,t=pb.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pV(e)||e<=this.resolve(n)}})}}bn.INVALID_DATE=p7,bt.prototype=bn.prototype,bt.INVALID_DATE=p7;var br=n(11865),bi=n.n(br),ba=n(68929),bo=n.n(ba),bs=n(67523),bu=n.n(bs),bc=n(94633),bl=n.n(bc);function bf(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pI.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(pw()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pN.isRef(o)&&o.isSibling?i(o.path,a):p_(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bl().array(r,n).reverse()}function bd(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bh(e){return(t,n)=>bd(e,t)-bd(e,n)}function bp(){return(bp=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bm(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bg=bh([]);class bv extends pH{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bg,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bb(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bp({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=pw()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pM.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bb(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bp({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pA({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bp({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pH&&i instanceof pH&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bh(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bf(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pI.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return pw()(i,e)&&(a=bp({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pg.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bm(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pg.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bu()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(bo())}snakeCase(){return this.transformKeys(bi())}constantCase(){return this.transformKeys(e=>bi()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pC()(this.fields,e=>e.describe()),e}}function by(e){return new bv(e)}function bw(){return(bw=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,bw({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pM.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pA({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!p_(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pf(e));return t.innerType=e,t}length(e,t=pv.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pV(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pv.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pv.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pV(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}b_.prototype=bE.prototype;var bS=by().shape({name:p2().required("Required"),url:p2().required("Required")}),bk=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hM,{initialValues:t,validationSchema:bS,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hj,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hR,{component:hJ,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hR,{component:hJ,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hR,{component:hJ,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hR,{component:hJ,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ox.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bx=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Edit Bridge",action:l.createElement(aL.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aK.Z,null,l.createElement(bk,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bT(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},ml=n(76023);function mf(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0||(i[n]=e[n]);return i}function mB(e,t){if(null==e)return{};var n,r,i=mY(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mU(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mX={};function mJ(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mX[t]||(mX[t]=mZ(e)),mX[t]}function mQ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mJ(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mV({},e,n[t])},t)}function m1(e){return e.join(" ")}function m0(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m2({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m2(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m0(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mV({},s,{className:m1(m)||void 0,style:mQ(s.className,Object.assign({},s.style,i),n)})}else d=mV({},s,{className:m1(s.className)});var g=h(t.children);return l.createElement(c,mq({key:o},d),g)}}let m3=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m4=/\n/g;function m5(e){return e.match(m4)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m9(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m7(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function ge(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mV({},i,"function"==typeof e?e(t):e)}function gt(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=ge(r,n,i);t.unshift(m7(n,h))}return f&l&&(d.style=mV({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gn(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return gt({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=ge(s,t,o);e.unshift(m7(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m5(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(gt({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=gt({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gc=n(98695),gl=n.n(gc);let gf=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gd=gs(gl(),gu);gd.supportedLanguages=gf;let gh=gd;var gp=n(64566);function gb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gm(){var e=gb(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gm=function(){return e},e}var gg=n0(gm()),gv=function(e){var t=e.children;return l.createElement(ii.Z,null,l.createElement(ie.default,{component:"th",scope:"row",colSpan:3},t))},gy=function(){return l.createElement(gv,null,"...")},gw=function(e){var t=e.children;return l.createElement(gv,null,t)},g_=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gw,null,i);if(t)return l.createElement(gy,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mR.Z,{defaultExpanded:o},l.createElement(mj.Z,{expandIcon:l.createElement(gp.Z,null)},a),l.createElement(mF.Z,{style:s},l.createElement(gh,{language:"toml",style:gu},n))))},gE=function(){var e=ry(gg,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"TOML Configuration"}),l.createElement(g_,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"TOML Configuration"}),l.createElement(g_,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(g_,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gS=n(34823),gk=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gx=(0,b.withStyles)(gk)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gS.N,A.wU);return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r7.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ii.Z,null,l.createElement(ie.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gT=function(){return l.createElement(iv,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(gE,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gx,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mP,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mS,null))))))},gM=function(){return l.createElement(gT,null)},gO=function(){return l.createElement(gM,null)},gA=n(44431),gL=1e18,gC=function(e){return new gA.BigNumber(e).dividedBy(gL).toFixed(8)},gI=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sf.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aK.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ob,{title:"Address"}),l.createElement(om,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(ob,{title:"Native Token Balance"}),l.createElement(om,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(ob,{title:"LINK Balance"}),l.createElement(om,{value:e.linkBalance?gC(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gU.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,{className:r.footer},l.createElement(aL.Z,{href:"/runs",component:tz},"View More"))))))});function vn(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vr(){var e=vn(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vr=function(){return e},e}var vi=5,va=n0(vr(),g7),vo=function(){var e=ry(va,{variables:{offset:0,limit:vi},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vt,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vi})},vs=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vu=(0,b.withStyles)(vs)(function(e){var t=e.classes,n=(0,A.v9)(gS.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ia.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vc=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vl=(0,b.withStyles)(vc)(function(e){var t=e.classes,n=e.job;return l.createElement(ii.Z,null,l.createElement(ie.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ip,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aA,{tooltip:!0},n.createdAt))))))});function vf(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vd(){var e=vf(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vd=function(){return e},e}var vh=n0(vd()),vp=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vb=(0,b.withStyles)(vp)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r7.Z,null,l.createElement(gz,{visible:o}),l.createElement(gG,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gH,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vl,{job:e,key:t})}))))});function vm(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vg(){var e=vm(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vg=function(){return e},e}var vv=5,vy=n0(vg(),vh),vw=function(){var e=ry(vy,{variables:{offset:0,limit:vv},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vb,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},v_=function(){return l.createElement(iv,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(vo,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gB,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vw,null))))),l.createElement(vu,null))},vE=function(){return l.createElement(v_,null)},vS=function(){return l.createElement(vE,null)},vk=n(87239),vx=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vT=n(5022),vM=n(78718),vO=n.n(vM);function vA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ii.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(ie.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(ie.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aA,{tooltip:!0},e.createdAt))),l.createElement(ie.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yp(t,e.status))},e.status.toLowerCase())))})))}),ym=n(16839),yg=n.n(ym);function yv(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=yg().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yy=n(94164),yw=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},y_=n(73343),yE=n(3379),yS=n.n(yE);function yk(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yy.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:y_.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yw,{data:e}))}))};function yC(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyB&&l.createElement("div",{className:t.runDetails},l.createElement(aL.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yY,{observationSource:n.observationSource})))});function y$(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vT.parse(e),!0}catch(t){return!1}})}),wK=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hM,{initialValues:t,validationSchema:wW,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hj,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hR,{component:hJ,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ox.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wV=n(50109),wq="persistSpec";function wZ(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wV.t8(wq,n),{toml:n}):{toml:wV.U2(wq)||""}}var wX=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wZ({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wV.t8("".concat(wq),t),n&&n(t)};return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"New Job"}),l.createElement(aK.Z,null,l.createElement(wK,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wJ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _O(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(_K,e)},_q=function(){var e=_V({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_H,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_Z=function(e){var t=e.csaKey;return l.createElement(ii.Z,{hover:!0},l.createElement(ie.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_T,{data:t.publicKey}))))};function _X(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _J(){var e=_X(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _J=function(){return e},e}var _Q=n0(_J()),_1=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r9.Z,null,l.createElement(sf.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ox.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(it.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,null,"Public Key"))),l.createElement(r7.Z,null,l.createElement(gz,{visible:o}),l.createElement(gG,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gH,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_Z,{csaKey:e,key:t})}))))};function _0(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(EO,e)};function EL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(EQ,e)},E4=function(){return os(E1)},E5=function(){return os(E0)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return ry(E2,e)};function E9(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(SV,e)};function SZ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kq(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kZ=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kV(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kK(kG({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r9.Z,null,l.createElement(aK.Z,null,l.createElement(k$,{object:n})))};function kX(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kJ(e){for(var t=1;t0&&l.createElement(ki,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kZ,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kP,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k9(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k9(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k7=n0(k8(),k5),xe=function(){var e=ry(k7,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(ij,null);if(r)return l.createElement(iN,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oo,null);default:return null}};function xt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xn(){var e=xt(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xn=function(){return e},e}var xr=n0(xn()),xi=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iw,null,"Job Runs")),t&&l.createElement(ij,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(yb,{runs:o}),l.createElement(ir.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xa(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xo(){var e=xa(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xo=function(){return e},e}var xs=n0(xo(),xr),xu=function(){var e=iF(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=ry(xs,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iN,{error:o}):l.createElement(xi,{loading:a,data:i,page:t,pageSize:n})},xc=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xu,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(xe,null)))},xl=by().shape({name:p2().required("Required"),uri:p2().required("Required"),publicKey:p2().required("Required")}),xf=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hM,{initialValues:t,validationSchema:xl,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hj,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ox.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xd=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Edit Feeds Manager"}),l.createElement(aK.Z,null,l.createElement(xf,{initialValues:r,onSubmit:n})))))};function xh(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xp(){var e=xh(["\n query FetchFeedsManagers {\n feedsManagers {\n results {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n }\n }\n }\n"]);return xp=function(){return e},e}var xb=n0(xp()),xm=function(){return ry(xb)};function xg(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(xZ,e)};function xJ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0?n.feedsManagers.results[0]:void 0;return n&&a?l.createElement(TH,{manager:a}):l.createElement(h.l_,{to:{pathname:"/feeds_manager/new",state:{from:e}}})},Tz={name:"Chainlink Feeds Manager",uri:"",publicKey:""},TG=function(e){var t=e.onSubmit;return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Register Feeds Manager"}),l.createElement(aK.Z,null,l.createElement(xf,{initialValues:Tz,onSubmit:t})))))};function TW(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return Mp(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mR.Z,{defaultExpanded:0===n,key:n},l.createElement(mj.Z,{expandIcon:l.createElement(gp.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Eu.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aA,{tooltip:!0},e.createdAt)))),l.createElement(mF.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ox.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gh,{language:"toml",style:gu,"data-testid":"codeblock"},e.definition)))}),l.createElement(oI,{open:null!=c,title:c?My[c.action].title:"",body:c?My[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mi,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function M_(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function ME(){var e=M_(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return ME=function(){return e},e}var MS=n0(ME(),Mg),Mk=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iw,null,"Job Proposal #",a.id))),l.createElement(T8,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(TU,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(Mw,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function Mx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.nextNonce&&t.append("nextNonce",e.nextNonce),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(55977),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(55977),a=n(47886),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(97779),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(55977),a=n(15857),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ri,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nr})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;nr,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(23564);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(23564),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},87462(e,t,n){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;tr})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(55977),p=__webpack_require__(15857),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t5(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t9("(",t5(e.variableDefinitions,", "),")"),i=t5(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t5([t,t5([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t9(" = ",r)+t9(" ",t5(i," "))},SelectionSet:function(e){return t6(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t9("",t,": ")+n,s=o+t9("(",t5(r,", "),")");return s.length>t2&&(s=o+t9("(\n",t8(t5(r,"\n")),"\n)")),t5([s,t5(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t9(" ",t5(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t5(["...",t9("on ",t),t5(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t9("(",t5(r,", "),")")," ")+"on ".concat(n," ").concat(t9("",t5(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t5(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t5(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t9("(",t5(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t5(["schema",t5(t," "),t6(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t5(["scalar",e.name,t5(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["type",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t9("(\n",t8(t5(n,"\n")),"\n)"):t9("(",t5(n,", "),")"))+": "+r+t9(" ",t5(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t5([t+": "+n,t9("= ",r),t5(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["interface",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t5(["union",t,t5(n," "),r&&0!==r.length?"= "+t5(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t5(["enum",t,t5(n," "),t6(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t5([e.name,t5(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t5(["input",t,t5(n," "),t6(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t9("(\n",t8(t5(n,"\n")),"\n)"):t9("(",t5(n,", "),")"))+(r?" repeatable":"")+" on "+t5(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t5(["extend schema",t5(t," "),t6(n)]," ")},ScalarTypeExtension:function(e){var t;return t5(["extend scalar",e.name,t5(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["extend type",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t5(["extend interface",t,t9("implements ",t5(n," & ")),t5(r," "),t6(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t5(["extend union",t,t5(n," "),r&&0!==r.length?"= "+t5(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t5(["extend enum",t,t5(n," "),t6(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t5(["extend input",t,t5(n," "),t6(r)]," ")}};function t4(e){return function(t){return t5([t.description,e(t)],"\n")}}function t5(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t6(e){return t9("{\n",t8(t5(e,"\n")),"\n}")}function t9(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t8(e){return t9(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n5(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n6(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n9(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n8(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e9(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n8(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n8(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r5=new(t_.mr?WeakMap:Map);function r6(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r5.set(e,(r5.get(e)+1)%1e15),n.apply(this,arguments)})}function r9(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r8=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r5.has(n)||(r5.set(n,0),r6(n,"evict"),r6(n,"modify"),r6(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r9(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r9(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r5.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r5.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e8(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r8(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r8&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n6(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r8(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e8(e5(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e9(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e8(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i6(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i9(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i8(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i6(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i5=[];function i6(e,t){var n=e.map;return n.has(t)||n.set(t,i5.pop()||{map:new Map}),n.get(t)}function i9(e,t){if(e===t||!t||i8(t))return e;if(!e||i8(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i9(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i9(t.map.get(n),e.map.get(n)))})}return a}function i8(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i8(r)&&(i5.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","VRFSpec","WebhookSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})();
\ No newline at end of file
+`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pU({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pA({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pA({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pU({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pU({},t,{value:e}))._validate(e,pU({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pM.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pM.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pr(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pd.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pd.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pd.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pj(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pk(e).map(e=>new pN(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pS(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pj({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pd.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pj({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pd.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pj({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let p$ of(pH.prototype.__isYupSchema__=!0,["validate","validateSync"]))pH.prototype[`${p$}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pY(this,e,t,n.context);return a[p$](r&&r[i],pU({},n,{parent:r,path:e}))};for(let pz of["equals","is"])pH.prototype[pz]=pH.prototype.oneOf;for(let pG of["not","nope"])pH.prototype[pG]=pH.prototype.notOneOf;pH.prototype.optional=pH.prototype.notRequired;let pW=pH;function pK(){return new pW}pK.prototype=pW.prototype;let pV=e=>null==e;function pq(){return new pZ}class pZ extends pH{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pm.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pV(e)||!0===e})}isFalse(e=pm.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pV(e)||!1===e})}}pq.prototype=pZ.prototype;let pX=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pJ=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pQ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,p1=e=>pV(e)||e===e.trim(),p0=({}).toString();function p2(){return new p3}class p3 extends pH{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p0?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=ph.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pV(t)||t.length===this.resolve(e)}})}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t.length>=this.resolve(e)}})}max(e,t=ph.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pV(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||ph.matches,params:{regex:e},test:t=>pV(t)||""===t&&n||-1!==t.search(e)})}email(e=ph.email){return this.matches(pX,{name:"email",message:e,excludeEmptyString:!0})}url(e=ph.url){return this.matches(pJ,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=ph.uuid){return this.matches(pQ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=ph.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:p1})}lowercase(e=ph.lowercase){return this.transform(e=>pV(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pV(e)||e===e.toLowerCase()})}uppercase(e=ph.uppercase){return this.transform(e=>pV(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pV(e)||e===e.toUpperCase()})}}p2.prototype=p3.prototype;let p4=e=>e!=+e;function p5(){return new p6}class p6 extends pH{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p4(e)}min(e,t=pp.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t>=this.resolve(e)}})}max(e,t=pp.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pV(t)||t<=this.resolve(e)}})}lessThan(e,t=pp.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pV(t)||tthis.resolve(e)}})}positive(e=pp.positive){return this.moreThan(0,e)}negative(e=pp.negative){return this.lessThan(0,e)}integer(e=pp.integer){return this.test({name:"integer",message:e,test:e=>pV(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pV(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pV(t)?t:Math[e](t))}}p5.prototype=p6.prototype;var p9=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p9.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p7=new Date(""),be=e=>"[object Date]"===Object.prototype.toString.call(e);function bt(){return new bn}class bn extends pH{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p7:new Date(e))})})}_typeCheck(e){return be(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pN.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pb.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pV(e)||e>=this.resolve(n)}})}max(e,t=pb.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pV(e)||e<=this.resolve(n)}})}}bn.INVALID_DATE=p7,bt.prototype=bn.prototype,bt.INVALID_DATE=p7;var br=n(11865),bi=n.n(br),ba=n(68929),bo=n.n(ba),bs=n(67523),bu=n.n(bs),bc=n(94633),bl=n.n(bc);function bf(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pI.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(pw()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pN.isRef(o)&&o.isSibling?i(o.path,a):p_(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bl().array(r,n).reverse()}function bd(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bh(e){return(t,n)=>bd(e,t)-bd(e,n)}function bp(){return(bp=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bm(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bg=bh([]);class bv extends pH{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bg,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bb(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bp({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=pw()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pM.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bb(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bp({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pA({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bp({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pH&&i instanceof pH&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bh(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bf(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pI.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return pw()(i,e)&&(a=bp({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pg.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bm(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pg.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bu()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(bo())}snakeCase(){return this.transformKeys(bi())}constantCase(){return this.transformKeys(e=>bi()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pC()(this.fields,e=>e.describe()),e}}function by(e){return new bv(e)}function bw(){return(bw=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,bw({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pM.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pA({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!p_(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pf(e));return t.innerType=e,t}length(e,t=pv.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pV(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pv.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pV(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pv.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pV(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}b_.prototype=bE.prototype;var bS=by().shape({name:p2().required("Required"),url:p2().required("Required")}),bk=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hM,{initialValues:t,validationSchema:bS,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hj,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hR,{component:hJ,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hR,{component:hJ,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hR,{component:hJ,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hR,{component:hJ,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ox.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bx=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Edit Bridge",action:l.createElement(aL.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aK.Z,null,l.createElement(bk,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bT(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},ml=n(76023);function mf(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0||(i[n]=e[n]);return i}function mB(e,t){if(null==e)return{};var n,r,i=mY(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mU(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mX={};function mJ(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mX[t]||(mX[t]=mZ(e)),mX[t]}function mQ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mJ(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mV({},e,n[t])},t)}function m1(e){return e.join(" ")}function m0(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m2({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m2(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m0(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mV({},s,{className:m1(m)||void 0,style:mQ(s.className,Object.assign({},s.style,i),n)})}else d=mV({},s,{className:m1(s.className)});var g=h(t.children);return l.createElement(c,mq({key:o},d),g)}}let m3=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m4=/\n/g;function m5(e){return e.match(m4)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m9(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m7(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function ge(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mV({},i,"function"==typeof e?e(t):e)}function gt(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=ge(r,n,i);t.unshift(m7(n,h))}return f&l&&(d.style=mV({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gn(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return gt({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=ge(s,t,o);e.unshift(m7(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m5(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(gt({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=gt({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gc=n(98695),gl=n.n(gc);let gf=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gd=gs(gl(),gu);gd.supportedLanguages=gf;let gh=gd;var gp=n(64566);function gb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gm(){var e=gb(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gm=function(){return e},e}var gg=n0(gm()),gv=function(e){var t=e.children;return l.createElement(ii.Z,null,l.createElement(ie.default,{component:"th",scope:"row",colSpan:3},t))},gy=function(){return l.createElement(gv,null,"...")},gw=function(e){var t=e.children;return l.createElement(gv,null,t)},g_=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gw,null,i);if(t)return l.createElement(gy,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mR.Z,{defaultExpanded:o},l.createElement(mj.Z,{expandIcon:l.createElement(gp.Z,null)},a),l.createElement(mF.Z,{style:s},l.createElement(gh,{language:"toml",style:gu},n))))},gE=function(){var e=ry(gg,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"TOML Configuration"}),l.createElement(g_,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"TOML Configuration"}),l.createElement(g_,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(g_,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gS=n(34823),gk=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gx=(0,b.withStyles)(gk)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gS.N,A.wU);return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r7.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ii.Z,null,l.createElement(ie.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gT=function(){return l.createElement(iv,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(gE,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gx,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mP,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mS,null))))))},gM=function(){return l.createElement(gT,null)},gO=function(){return l.createElement(gM,null)},gA=n(44431),gL=1e18,gC=function(e){return new gA.BigNumber(e).dividedBy(gL).toFixed(8)},gI=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sf.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aK.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ob,{title:"Address"}),l.createElement(om,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(ob,{title:"Native Token Balance"}),l.createElement(om,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(ob,{title:"LINK Balance"}),l.createElement(om,{value:e.linkBalance?gC(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gU.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,{className:r.footer},l.createElement(aL.Z,{href:"/runs",component:tz},"View More"))))))});function vn(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vr(){var e=vn(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vr=function(){return e},e}var vi=5,va=n0(vr(),g7),vo=function(){var e=ry(va,{variables:{offset:0,limit:vi},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vt,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vi})},vs=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vu=(0,b.withStyles)(vs)(function(e){var t=e.classes,n=(0,A.v9)(gS.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ia.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vc=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vl=(0,b.withStyles)(vc)(function(e){var t=e.classes,n=e.job;return l.createElement(ii.Z,null,l.createElement(ie.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ip,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aA,{tooltip:!0},n.createdAt))))))});function vf(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vd(){var e=vf(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vd=function(){return e},e}var vh=n0(vd()),vp=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vb=(0,b.withStyles)(vp)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r7.Z,null,l.createElement(gz,{visible:o}),l.createElement(gG,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gH,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vl,{job:e,key:t})}))))});function vm(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vg(){var e=vm(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vg=function(){return e},e}var vv=5,vy=n0(vg(),vh),vw=function(){var e=ry(vy,{variables:{offset:0,limit:vv},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vb,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},v_=function(){return l.createElement(iv,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(vo,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gB,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vw,null))))),l.createElement(vu,null))},vE=function(){return l.createElement(v_,null)},vS=function(){return l.createElement(vE,null)},vk=n(87239),vx=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vT=n(5022),vM=n(78718),vO=n.n(vM);function vA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ii.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(ie.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(ie.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aA,{tooltip:!0},e.createdAt))),l.createElement(ie.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yp(t,e.status))},e.status.toLowerCase())))})))}),ym=n(16839),yg=n.n(ym);function yv(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=yg().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yy=n(94164),yw=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},y_=n(73343),yE=n(3379),yS=n.n(yE);function yk(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yy.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:y_.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yw,{data:e}))}))};function yC(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyB&&l.createElement("div",{className:t.runDetails},l.createElement(aL.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yY,{observationSource:n.observationSource})))});function y$(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vT.parse(e),!0}catch(t){return!1}})}),wK=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hM,{initialValues:t,validationSchema:wW,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hj,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hR,{component:hJ,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ox.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wV=n(50109),wq="persistSpec";function wZ(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wV.t8(wq,n),{toml:n}):{toml:wV.U2(wq)||""}}var wX=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wZ({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wV.t8("".concat(wq),t),n&&n(t)};return l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"New Job"}),l.createElement(aK.Z,null,l.createElement(wK,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wJ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _O(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(_K,e)},_q=function(){var e=_V({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_H,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_Z=function(e){var t=e.csaKey;return l.createElement(ii.Z,{hover:!0},l.createElement(ie.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_T,{data:t.publicKey}))))};function _X(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _J(){var e=_X(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _J=function(){return e},e}var _Q=n0(_J()),_1=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r9.Z,null,l.createElement(sf.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ox.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(it.Z,null,l.createElement(ii.Z,null,l.createElement(ie.default,null,"Public Key"))),l.createElement(r7.Z,null,l.createElement(gz,{visible:o}),l.createElement(gG,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gH,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_Z,{csaKey:e,key:t})}))))};function _0(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(EO,e)};function EL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(EQ,e)},E4=function(){return os(E1)},E5=function(){return os(E0)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return ry(E2,e)};function E9(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(SV,e)};function SZ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kq(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kZ=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kV(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kK(kG({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r9.Z,null,l.createElement(aK.Z,null,l.createElement(k$,{object:n})))};function kX(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kJ(e){for(var t=1;t0&&l.createElement(ki,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kZ,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kP,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k9(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k9(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k7=n0(k8(),k5),xe=function(){var e=ry(k7,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(ij,null);if(r)return l.createElement(iN,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oo,null);default:return null}};function xt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xn(){var e=xt(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xn=function(){return e},e}var xr=n0(xn()),xi=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iw,null,"Job Runs")),t&&l.createElement(ij,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r9.Z,null,l.createElement(yb,{runs:o}),l.createElement(ir.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xa(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xo(){var e=xa(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xo=function(){return e},e}var xs=n0(xo(),xr),xu=function(){var e=iF(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=ry(xs,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iN,{error:o}):l.createElement(xi,{loading:a,data:i,page:t,pageSize:n})},xc=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xu,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(xe,null)))},xl=by().shape({name:p2().required("Required"),uri:p2().required("Required"),publicKey:p2().required("Required")}),xf=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hM,{initialValues:t,validationSchema:xl,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hj,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hR,{component:hJ,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Feeds Manager operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ox.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xd=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Edit Feeds Manager"}),l.createElement(aK.Z,null,l.createElement(xf,{initialValues:r,onSubmit:n})))))};function xh(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xp(){var e=xh(["\n query FetchFeedsManagers {\n feedsManagers {\n results {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n }\n }\n }\n"]);return xp=function(){return e},e}var xb=n0(xp()),xm=function(){return ry(xb)};function xg(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return ry(xZ,e)};function xJ(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0?n.feedsManagers.results[0]:void 0;return n&&a?l.createElement(TH,{manager:a}):l.createElement(h.l_,{to:{pathname:"/feeds_manager/new",state:{from:e}}})},Tz={name:"Chainlink Feeds Manager",uri:"",publicKey:""},TG=function(e){var t=e.onSubmit;return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r9.Z,null,l.createElement(sf.Z,{title:"Register Feeds Manager"}),l.createElement(aK.Z,null,l.createElement(xf,{initialValues:Tz,onSubmit:t})))))};function TW(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return Mp(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ox.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ox.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mR.Z,{defaultExpanded:0===n,key:n},l.createElement(mj.Z,{expandIcon:l.createElement(gp.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Eu.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aA,{tooltip:!0},e.createdAt)))),l.createElement(mF.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ox.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gh,{language:"toml",style:gu,"data-testid":"codeblock"},e.definition)))}),l.createElement(oI,{open:null!=c,title:c?My[c.action].title:"",body:c?My[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mi,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function M_(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function ME(){var e=M_(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return ME=function(){return e},e}var MS=n0(ME(),Mg),Mk=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(iv,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iw,null,"Job Proposal #",a.id))),l.createElement(T8,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(TU,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(Mw,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function Mx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.nextNonce&&t.append("nextNonce",e.nextNonce),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(55977),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(55977),a=n(47886),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(97779),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(55977),a=n(15857),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ri,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nr})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;nr,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(23564);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(23564),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},87462(e,t,n){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;tr})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(55977),p=__webpack_require__(15857),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v